Fundamentals (Docs)


Type Inference

In Java SE 7 and later, you can replace the type arguments required to invoke the constructor of a generic class 
with an empty set of type parameters (<>) as long as the compiler can determine, or infer, the type arguments 
from the context. This pair of angle brackets, <>, is informally called the diamond. For example, you can create 
an instance of Box<Integer> with the following statement:

	Box<Integer> integerBox = new Box<>();

Type inference enables you to invoke a generic method as you would an ordinary method, without specifying a 
type between angle brackets.

	public class BoxDemo {
	    public static void main(String[] args) {
		java.util.ArrayList<Box<Integer>> listOfIntegerBoxes = new java.util.ArrayList<>();  // diamond JDK 7
		    //java.util.ArrayList<Box<Integer>> listOfIntegerBoxes = new java.util.ArrayList<Box<Integer>>();
		BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes);
		BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes); 
		    // invoke a generic method without specifying a type
		BoxDemo.addBox(10, listOfIntegerBoxes); 
		//BoxDemo.addBox("30", listOfIntegerBoxes); 
		    // compiler error "30" is String not Integer
	    public static <U> void addBox(U u, java.util.ArrayList<Box<U>> boxes) {
		Box<U> box = new Box<>(); // diamond JDK 7
		    //Box<U> box = new Box<U>();
	    public static <U> void outputBoxes(java.util.ArrayList<Box<U>> boxes) {
		int i=0;
		for(Box<U> box : boxes) {
		    System.out.println("Box #" + i + " contains [" + box.get() + "]");

If you omit the type parameters, the Java compiler automatically infers (from the method's arguments) that the 
type parameter is Integer:

	BoxDemo4.addBox(Integer.valueOf(20), listOfIntegerBoxes);

In Java SE 7 and later, you can substitute the parameterized type of the constructor with an empty set of type 
parameters (<>).
Note that to take advantage of automatic type inference during generic class instantiation, you must specify the 

	Map<String, List<String>> myMap = new HashMap<>();
	// Map<String, List<String>> myMap = new HashMap<String, List<String>>();

You can only use type inference if the parameterized type of the constructor is obvious from the context.

	// compile
	java.util.List<String> list = new java.util.ArrayList<>();
        list.add("A"); // compile
	list.add(new ArrayList<>()); // compile error
		// this statement should fail since addAll expects
		// Collection<? extends String>

	// The following statements compile:
	List<? extends String> list2 = new ArrayList<>();