Say, I have a method:
public static <T> Collection<T> addToCollection(T element, Collection<T> collection) {
collection.add(element);
return collection;
}
And then when trying to compile this code:
Integer i = 42;
Collection<Integer> result = addToCollection(i, Collections.emptyList());
I get an error Type mismatch: cannot convert from Collection<Object> to Collection<Integer>
.
Could anyone explain why the type system cannot infer that Collections.emptyList() should be of type Collection<Integer>
?
The example above is obviously quite artificial, but I stumble upon that limitation all the time and it's really annoying. After having read Effective Java I have found out that you can simply do Collections.<Integer>emptyList()
(must say, that was quite a revelation for me at the time) and have everything compiling smoothly, but when you have some complicated type then it really is a nuisance.
I'm just wondering if this is some sort of bug, or are there any valid reasons for it to work that way?
While type inference is really useful for local variables, it should not be used for public APIs which have to be unambiguously documented. And sometimes the types really are critical for understanding what's going on in the code. In such cases, it would be foolish to rely on type inference alone.
Java SE 7 supports limited type inference for generic instance creation; you can only use type inference if the parameterized type of the constructor is obvious from the context.
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
So, I can imagine that type inference was probably not supported because Java was aimed at programmers coming from C++, Pascal, or other mainstream languages that did not have it (principle of least surprise).
The type inference system has been improved in Java 8, with the introduction of target typing, in order to give more expressivity to streams and lambdas. As a consequence your code compiles with Java 8.
More about it in the updated tutorial, with a very similar example towards the very bottom of the page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With