Reputation: 137
Look, we've got come code:
public class Test2 {
public static void main(String... args) {
ArrayList<Exception> a = new ArrayListFactory().create(new RuntimeException());
ArrayList<Exception> b = new ArrayListFactory().create("Z");
}
}
class ArrayListFactory {
public <T> ArrayList<T> create(T example) {
return new ArrayList<T>(10);
}
}
and an compilation error on second statement:
Error:(15, 63) java: incompatible types: inference variable T has incompatible bounds
equality constraints: java.lang.Exception
lower bounds: java.lang.String
ArrayList<Exception>
another ArrayList<RuntimeException>
, doesnt it clash with java rules?Exception
type argument for create
. Does it check that method's return type matches it's argument type as it's defined in ArrayListFactory class? It seems that this method call shall be resolved dynamically, why is compiler sure that it's processing the correct method?Upvotes: 0
Views: 98
Reputation: 2841
In this statement:
ArrayList<Exception> b = new ArrayListFactory().create("Z");
The compiler uses type inference (from the declaration ArrayList<Exception>
) to add a constraint on the generic return type of create()
. It's called a Target Type. The target type of an expression is the data type that the Java compiler expects depending on where the expression appears.
In this case, T should be a subclass of Exception. RuntimeException
is thus fine; but String
is not.
This feature appeared with Java 8. More information on it : http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html
Upvotes: 0
Reputation: 131346
1) First call
ArrayList<Exception> a = new ArrayList<RuntimeException>();
is not a legal use of Generics in Java. You can go to Explanation of the get-put principle to understand.
2) Second call
The inference of the T
Type depends on the returned type declared from the caller.
Here the caller declares the returned type as Exception
:
ArrayList<Exception> b = new ArrayListFactory().create("Z");
Whereas the compilation error :
Error:(15, 63) java: incompatible types: inference variable T has incompatible
bounds equality constraints: java.lang.Exception
To pass a String :
ArrayList<String> b = new ArrayListFactory().create("Z");
Upvotes: 0
Reputation: 3507
All Generic type will assign at compile time so compiler will infer type from your assignment and its expected both to be same, but in your case its different, so it will give type mismatch error, change code like this to fix the errors.
public class Test2 {
public static void main(String... args) {
ArrayList<RuntimeException> a = new ArrayListFactory().create(new RuntimeException());
ArrayList<String> b = new ArrayListFactory().create("Z");
}
}
Upvotes: 1