Because the compiler can infer the type from the variable declaration.
Example:
List<String> list = Lists.newArrayList(),
the compiler will understand that the type of the collection (the type of E) will be <String>
, since you expect to get a List of String.
It was useful to avoid rewriting entire <> arguments, but with Java7 and diamond operator you can avoid it using
List<String> list = new ArrayList<>();
(Imaginate it was a List<List<String>>
you should rewrite List<List<String>>
)
I found this for you:
The Java compiler takes advantage of target typing to infer the type parameters of a generic method invocation. The target type of an expression is the data type that the Java compiler expects depending on where the expression appears. Consider the method Collections.emptyList, which is declared as follows:
static <T> List<T> emptyList();
Consider the following assignment statement:
List<String> listOne = Collections.emptyList();
This statement is expecting an instance of List; this data type is the target type. Because the method emptyList returns a value of type List, the compiler infers that the type argument T must be the value String. This works in both Java SE 7 and 8. Alternatively, you could use a type witness and specify the value of T as follows:
List<String> listOne = Collections.<String>emptyList();
However, this is not necessary in this context. It was necessary in other contexts, though. Consider the following method:
void processStringList(List<String> stringList) {
// process stringList
}
Suppose you want to invoke the method processStringList with an empty list. In Java SE 7, the following statement does not compile:
processStringList(Collections.emptyList());
The Java SE 7 compiler generates an error message similar to the following:
List<Object> cannot be converted to List<String>
The compiler requires a value for the type argument T so it starts with the value Object. Consequently, the invocation of Collections.emptyList returns a value of type List, which is incompatible with the method processStringList. Thus, in Java SE 7, you must specify the value of the value of the type argument as follows:
processStringList(Collections.<String>emptyList());
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:
processStringList(Collections.emptyList());
See Target Typing in Lambda Expressions for more information.
Read this