Given that
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
...
Why a String return is not valid?
>Solution :
You misunderstand what this means. You apparently think it means: "T is anything that is a Comparable or some subtype of it".
This is incorrect. after all, that concept is represented by… Comparable<String> itself.
No, you read this stuff as ‘unknown’:
public void <T extends Comparable<T>> T getValue() { ... }
means:
"There is an unknown type. The caller knows what it is, but this code does not and cannot possibly figure it out. All we know is, the caller picked it, every caller can pick a different one, and, whatever choice was made, it’s at least a subtype of Comparable<T>."
Your code must work such that it is valid for all possible choices any caller could make.
That sounds impossible, and indeed it is – unless you know the trick. Which is, that generics link things. The trick to returning a thing of a type you don’t know, is to get it from the caller, which does know. Here is a trivial example:
public <T> T print(T in) {
System.out.println(in);
return in;
}
In this example the same unknown happens: T is an unknown type; the caller knows it, you don’t and can’t know it. Nevertheless, this code is valid for every possible choice the caller could make, because what you return is something you got from the caller in the first place.
If you want to write a method that returns String just.. write public String getValue() {return "hola";}. With that, you can assign it to anything that ‘works’. For example:
Comparable<String> str = getValue();
This works – but is kinda useless here (just assign it to a variable of type String; all String values are also Comparable<String>; any method that requires a Comparable<String> can be passed a string and it’ll work.
NB: There are situations where you write a method that has a type param which is used in only one spot – the return type, however, these methods always fall into one of these categories:
- They get around not knowing what to return by literally always ending in
return null;– becausenullis every type at once, and therefore, necessarily compatible with T even if we have no idea what T is. - They get around not knowing what to return by never returning.
while (true) ;is one way to do it. Always ending inthrow new SomeException();is another. if you never actually return a value, then it’s no problem that your method should return a value of an unknown type, which is impossible. - They hack it with an ugly cast:
return (T) something;. This generates a warning, because, the compiler has no idea. It’s just going by your word that things will work out. If they don’t, and why should they, you end up withClassCastExceptionerrors on lines that have no casts in them. Bad idea – confusing code is bad, confusing errors are worse.
