I have a method which returns a List<Property<?>>
.
Property is a type having one generic parameter:
public class Property<T extends Comparable<T>> { ... }
Having a list of mixed-typed properties, I cannot know what type parameter a specific element has.
I would like to do something like that:
List<Property<?>> list = getList();
for(Property<?> crt : list)
{
PropertyWrapper<?> crtWrapper = new PropertyWrapper(crt.getGenericType());
// I know this doesn't exist ----^
}
In one sentence: I need the PropertyWrapper
to have the same generic template argument as the current Property
does. Is there any way to do this?
I could apply a suggestion as stated in https://stackoverflow.com/a/3437930/146003 but even if I do this, how to instanciate the appropriate PropertyWrapper<XXX>
then, only having an instance of Class<T>
?
I can modify Property<?>
if required. I also don't mind if reflection needs to be used (I assume it needs to be)
EDIT: I forgot something. In fact I cannot instanciate the wrapper by the line
PropertyWrapper<?> crtWrapper = new PropertyWrapper(crt.getGenericType());
because I have specialized subclasses (PropertyWrapper_String
).
Now I see two possibilities:
1: Instanciate the class by string:
String strGenericType = "";
Class<?> wrapperClass = Class.forName("PropertyWrapper_" + strGenericType);
2: Is there any way to specialize a generic class without creating a subclass?
Many thanks in advance for your tips
Okay I'm going to answer myself.
I'm now passing an instance of Class<?>
to the Property
-class.
Then I extract the basic name of the property and simply cut away "java.lang."
which is possibly as in most cases, I'm doing this to primitive data types - resp. their autoboxing classes.
Further, I just instanciate a new instance of the wrapper by name and pass the to be wrapped property as a parameter to the constructor which applys for that.
Here some code for the interested ones among you:
String template = "..."; // some package definition
for (Property<?> crt : bag)
{
String className = template + crt.getClassName();
Class<? extends PropertyWrapper<?>> wrapperClass = null;
wrapperClass = (Class<? extends PropertyWrapper<?>>) Class.forName(className);
Constructor<? extends PropertyWrapper<?>> constructor = wrapperClass.getConstructor(new Class<?>[] {Property.class});
PropertyWrapper<?> wrapper = constructor.newInstance(crt);
// Further operations using the wrapper
}
for simplicity, I left out the error handling part.