Consider the following code:
// ...
public class BaseClass
{
public BaseClass (int theParam)
{
// ...whatever...
}
}
public class DerivedType
{
// ...Content does not matter...
}
// ...elsewhere:
public <ElemType extends BaseClass> boolean doIt (ArrayList<ElemType> target)
{
ElemType newElem=new ElemType (5) ; // "Cannot instantiate this type"
// ...other code does not matter...
return true ;
}
// ..
How can I create an instance of type ElemType in doIt?
The construct shown yields the error indicated.
ElemType.newInstance does not exist, which surprises me.
I’ve read practically all FAQs, answers and googleable material, but I cannot find anything helpful.
EDIT:
Yes I know reflection has its downsides, and is not the ultimate solution, for numerous reasons. The question is not “should I do it”, but “how would I do it”.
As mentioned, type erasure of generic types does not allow that. But you can achieve what you want like this:
And now doIt() method gets the class argument for reference:
And you should call it like this:
Hope that helps 🙂
Note that, one may really want to be hacky and get rid of the class parameter and try this:
In fact I thought so before the second edit 🙂 But this gets a “java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class” exception as you mention (I didn’t see it because of an overlooked catch statement). In short, Java runtime system does not store the parameterized types (in favor of backwards compatibility; so this may change in the future).
So, it looks like it is not possible without ‘touching’ some class.
However, other than the mentioned methods, I can think of two more things. First, if both the BaseClass and the DerivedType ‘D’ class implement clone() method, you can get a clone of an object from the array and then use it:
Polymorphism will take care of the rest 🙂
The second one is not a real ‘solution’, but can be used if all you want is a new instance for an array of objects parameterized by type. Type Erasure only happens for parameterized types, but it does not happen for basic arrays (arrays are reified in JVM). So if we have the freedom to change the signature of the method and working with arrays is ok, then the following would work:
Note: Super type tokens would not work for this problem if we cannot introduce new parameters. Please correct me if I’m wrong.