I am reading generics chapter in “Thinking in Java 4th edition” and there is an example:
class Fruit{}
class Apple extends Fruit {}
…
static <T> void writeExact(List<T> list, T item) {
list.add(item);
}
static List<Apple> apples = new ArrayList<>();
static List<Fruit> fruit = new ArrayList<>();
static void f1() {
writeExact(apples, new Apple());
// writeExact(fruit, new Apple()); // Error:
// Incompatible types: found Fruit, required Apple
}
static <T> void writeWithWildcard(List<? super T> list, T item) {
list.add(item);
}
static void f2() {
writeWithWildcard(apples, new Apple());
writeWithWildcard(fruit, new Apple());
}
Those commented line, where error is indicated, doesn’t produce any error at all both in 6 and 7 Java. It seems weird for me, as writeExact method accepts only exact type of parameter. So why does it work? And since it works what is a purpose of supertype wildcards?
edit
so i got it and want to clarify one more thing:
who is the boss in type inference with wildcards? return type, first parameter, second parameter, … . I mean that if SomeClass.<Fruit>method(…) is not specified
It works because the
TinwriteExactis a type variable on the method itself. Look, it’s right there before the void return type:That means that whenever you call it, its
Ttakes on the type needed to accept its arguments, as long as there is one. You can call it with any list and an object that would fit in that list.Perhaps it makes it clearer to explicitly give the type argument, rather than letting the compiler infer it (you need to use the class’s name to do this for a static method; i will assume it is
MyClass):In the second call,
Thas the valueFruit, which means the first argument must be aList<Fruit>, which it is, and the second must be aFruit, which it is, becauseAppleis a subtype ofFruit.The rules for implicitly assigning type arguments are given in section 15.12.2.7 of the Java Language Specification. At least, i think they are; it’s not exactly an easy read.
I would guess that the code in the book is not exactly the same as the code you give above. If it is, then it it definitely incorrect, and you should write to Mr Eckel and tell him.