In https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html, it is suggested to implement a method
public static double sumOfList(List<? extends Number> list) {
double s = 0.0;
for (Number n : list)
s += n.doubleValue();
return s;
}
and then to invoce it with
List<Integer> li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfList(li));
public static <T> double sumOfList(List<T extends Number> list)
?public static <T extends Number> double sumOfList(List<T> list)
equivalent? If so, is it of less good style?System.out.println("sum = " + sumOfList<Integer>(li));
?
- Why is it illegal to put
Because that's just not the syntax.
T
is a type variable, the bounds have to be specified where the type variable is declared (within the <>
preceding the method return type), not where it is used (in the same way that the type of a variable has to be specified where it is declared, not where it is used, e.g. String foo
, not foo.<String>contains("a")
).
- Is ... Equivalent?
Not quite.
The advantage of declaring a type variable and using that in the List<T>
is that you can then declare variables of that type in the method.
For example:
T element = list.get(0);
list.set(0, element);
is not legal for a List<? extends Number>
, but is for a List<T>
.
You can also do things like using T
in the return type of the method and/or other parameters.
But, if you don't need to do any of these things, you don't need a type variable, so don't declare one, just as you shouldn't declare variables you don't need.
- When using the aforementioned code, why is it illegal to write
Because that's just not the syntax.
However, you can write:
System.out.println("sum = " + TheContainingClass.<Integer>sumOfList(li));
(Or e.g. this.<Integer>sumOfList(...)
, if it were a non-static method)
i.e. the <>
comes before the method name, and the method invocation needs to be qualified.
This <Integer>
is sometimes called a "type witness", although that is not a term defined in the spec.