In the Java specification (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9), new has the following form:
ClassInstanceCreationExpression ::=
| new TypeArguments_opt TypeDeclSpecifier TypeArgumentsOrDiamond_opt
( ArgumentListopt ) ClassBodyopt
| Primary . new TypeArguments_opt Identifier TypeArgumentsOrDiamond_opt
( ArgumentListopt ) ClassBodyopt
What is the purpose of the first optional type argument list after the new? I was not able to find it from my read of section 15.9 (all references to type arguments list seem to refer to the list after the type/identifier). Testing out random bits on the standard Java compiler yields confusing results:
public class Foo<T> { }
// ...
Foo<Integer> t1 = new <Integer> Foo<Integer>(); // works
Foo<Integer> t2 = new <Integer> Foo(); // works -- unchecked warning missing the type arg after Foo
Foo<Integer> t3 = new <Boolean> Foo<Integer>(); // works
Foo<Integer> t4 = new <Float, Boolean> Foo<Integer>(); // works
Foo<Integer> t5 = new <NotDefined> Foo<Integer>(); // fails -- NotDefined is undefined
On theses simple examples, it doesn't seem like this first parameter list does anything meaningful although it parses and checks for the validity of its arguments.
It is used to prevent a specific constructor from being called implicitly when constructing an object. For example, without the explicit keyword, the following code is valid C++: Array a = 10; This will call the Array single-argument constructor with the integer argument of 10.
A Constructor with arguments(or you can say parameters) is known as Parameterized constructor. As we discussed in the Java Constructor tutorial that a constructor is a special type of method that initializes the newly created object.
Passing Objects As ArgumentsWe can also pass arguments while creating other instances of a class. In this way parameterized constructors fulfills the need to copy one object's values to another. In the above example, we initialize obj1 using a string.
Explanation: Here, we see a default constructor with no arguments and a default constructor with one default argument. The default constructor with argument has a default parameter x, which has been assigned a value of 0.
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
.
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.
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