We have following code:
class MyClass<T>{
public void method(){
List<T>= new ArrayList<T>();
}
}
Does the following reason is correct? We are trying to instanciate ArrayList<T>
, where T
is type parameter, from a non static method. method
needs in a specific instance of MyClass<T>
. For instanciate MyClass<T>
compiler must know type T
explicitly. As i understood, compiler mark type parametr T
in a non static context as known and hence we can instanciate ArrayList<T>
.
But if we write the following code:
class MyClass<T>{
public void method(){
List<T>= new ArrayList<T>();
new T();// Compile Error
}
}
We have a compile error. I know that we can apply abstract factory pattern or use reflection for that needs. But new
operator requires a specific type. Type parametr T
is specific i non static context. Where i've wrong reasoning?
As i understood, compiler mark type parametr T in a non static context as known and hence we can instanciate ArrayList.
No. Even in non-static context, compiler doesn't know what type T
denotes. The reason why new ArrayList<T>();
works is, compiler knows that ArrayList<E>
has a 0-arg constructor. The type parameter T
will just be replaced by actual type argument. And it can be any type. And since you can create an ArrayList
of anytype, that is fine.
But new operator requires a specific type. Type parametr T is specific i non static context. Where i've wrong reasoning?
In case of new T();
, again since the compiler doesn't know what type T
is, hence it doesn't know, whether there is any accessible 0-arg constructor of T
or not. Consider a class as below:
class Test {
private int value;
public Test(int value) { this.value = value; }
}
And then you instantiate your generic class as:
MyClass<Test> obj = new MyClass<Test>();
Now, assume that compiler allows new T();
, then for this instantiation, it is like doing - new Test();
. But there is no 0-arg constructor in Test
. So, how would you expect that code to behave at runtime? It would certainly throw exception. This is what compiler prevents, by showing a compiler error.
We can add more information to the type parameter T
by specifying a bound - T extends Number
. But that will only allow us to access methods of type parameter. Constructor is still not accessible.