I have the following two classes:
public class GenericNumberOperation {
public GenericNumberOperation() {}
public T getSomeValu
Forget about what you're trying to use this for. We're only going to look at this from a language perspective.
The declaration
public <T extends Number> T getSomeValue (boolean tf) {
defines a new type T
that is bounded by Number
. That means that a caller can only bind Number
or any subtype of Number
to T
when invoking the method. Within the method, you don't know what that type might be.
You therefore can't do
T number = new Double(1.0);
because you don't know that T
is Double
. If I invoked the method as
Float f = genOp.getSomeValue(true);
T
should have been Float
. The compiler can't guarantee type safety and therefore rejects it (the assignment within the method, if it had been allowed, a ClassCastException
would have been thrown at runtime). If you use a cast, you're telling the compiler that you're sure about what you're doing. It'll warn you, but it will trust you.
Similarly, the declaration
public <T> T getSomeValue(boolean tf)
defines a new type T
that is unbounded. That means that you can bind any type to T
, which makes the problem even greater. I can now do
String f = genOp.getSomeValue(true);
As @Sotirios Delimanolis wrote, you cannot even run that code.
Try this one:
@SuppressWarnings("unchecked")
public <T extends Number> T getSomeValue(boolean tf) {
T number;
if (tf) {
number = (T) new Double(1.0);
} else {
number = (T) new Integer(11);
}
return number;
}