In the Java specification (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9), new has the following form:
ClassInstanceCreationExpressio
You can add useless type arguments for method invocations, weird stuff like
Math.<Runnable>max(1,2);
System.out.<Button>println();
see http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.1-200-E
a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.
This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.
Constructors can declare type parameters too
public class Main {
public static class Foo<T> {
public <E> Foo(T object, E object2) {
}
}
public static void main(String[] args) throws Exception {
Foo<Integer> foo = new <String> Foo<Integer>(1, "hello");
}
}
That's what the <String>
preceding the constructor call is for. It is the type argument for the constructor.
The following
Foo<Integer> foo = new <String> Foo<Integer>(1, new Object());
fails with
The parameterized constructor Foo(Integer, String) of type Main.Foo is not applicable for the arguments (Integer, Object)
In your last
Foo<Integer> t5 = new <NotDefined> Foo<Integer>(); // fails -- NotDefined is undefined
NotDefined
is just not a type that is found during compilation. If it was, it would just give you a warning that it is unused
.