Reputation: 4940
This is how Java Tutorials define type inference:
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. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.
Below, it explains type inference using all examples of generics.
My questions is : Do type inference in Java only applies when generics come into play ? If not, an example or two will be helpful where we can see it ?
Upvotes: 5
Views: 101
Reputation: 140525
My first thought was: "not necessarily"; as the compiler since ever would have into analyzing method arguments to select a matching method when overloading takes places (like in understanding which foo(int) versus foo(long) versus foo(double) should be called for for some foo(x)
).
But well, this is about terminiology. So the fact that "some computations" are required to detect the correct overloaded method doesn't mean that the "java fathers" think that these computations account for "type inference".
To the contrary: the Java language specification has a whole chapter about type inference; and when you study that closely, it is "only" about generic types and lambdas.
So the answers seems to be: when Java people use that term, it is solely about generics/lambdas; and not about other situations where the argument types need to be analyzed.
Upvotes: 1
Reputation: 37604
It would not make much sense to have type inference in a true non-generic environment, because otherwise you and the compiler would already know the type and don't need the compiler to interfere anything.
However the closes example I could find is about Target Types
. From the docs
Take a method which is declared as this
void processStringList(List<String> stringList) {
// process stringList
}
And you call it with this
processStringList(Collections.emptyList());
Since Collections.emptyList()
is returning a List<Object
if no target is specified it will throw an error
List<Object> cannot be converted to List<String>
Here the compiler is not able to interfere the type arguments for List<>
. You have to explicitly provide the target type like
processStringList(Collections.<String>emptyList());
However with JDK 8 that's not necessary anymore. Oracle docs Type Inference
This is no longer necessary in Java SE 8. The notion of what is a target type has been expanded to include method arguments, such as the argument to the method processStringList. In this case, processStringList requires an argument of type List. The method Collections.emptyList returns a value of List, so using the target type of List, the compiler infers that the type argument T has a value of String. Thus, in Java SE 8, the following statement compiles:
So in the last example the compiler interferes the type argument to get a List<String>
from Collections.emptyList()
.
Upvotes: 1
Reputation: 3682
In lambdas you do not have to specify argument types, and return types as well, they are automatically deduced. For example:
listOfStrings.stream().
map((aString) -> {
//do something
anObject anobject = new anObject();
return anobject;})
.collect(Collectors.toList());
The type of the returned list is List<anObject>
, and I did not have to specify that aString is of type String as it is infered by the listOfStrings type.
Upvotes: 2