If I have an abstract class like this:
public abstract class Item
{
private Integer value;
public Item()
{
value=new Integer(0);
}
public Item(Integer value)
{
this.value=new Integer();
}
}
And some classes deriving from Item like this:
public class Pencil extends Item
{
public Pencil()
{
super();
}
public Pencil(Integer value)
{
super(value);
}
}
I have not understood why I can't call the constructor using a generic:
public class Box <T extends Item>
{
T item;
public Box()
{
item=new T(); // here I get the error
}
}
I know that is possible to have a type which hasn't a constructor, but this case is impossible because Pencil has the constructor without parameters, and Item is abstract.
But I get this error from eclipse:
cannot instanciate the type T
I don't understand why, and how to avoid this?
You must be sure the type defines the constructor you want to invoke. You cannot constrain the generic type T to types that have a particular constructor other than the default constructor. (E.g. where T : new(Guid) does not work.)
Generic constructors are the same as generic methods. For generic constructors after the public keyword and before the class name the type parameter must be placed. Constructors can be invoked with any type of a parameter after defining a generic constructor.
Constructors are similar to methods and just like generic methods we can also have generic constructors in Java though the class is non-generic. Since the method does not have return type for generic constructors the type parameter should be placed after the public keyword and before its (class) name.
This is because Java uses erasure to implement generics, see this:
To quote the relevant parts from the above Wikipedia article:
Generics are checked at compile-time for type-correctness. The generic type information is then removed in a process called type erasure.
As a result of type erasure, type parameters cannot be determined at run-time.
Consequently, instantiating a Java class of a parameterized type is impossible because instantiation requires a call to a constructor, which is unavailable if the type is unknown.
You can go around this by actually providing the class yourself. This is well explained here:
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