I would like to create an instance of a specified class using its name. My code is shown below.
I get a compiler warning. Am I doing this the right way? Is it even possible to use the name of a class and get an instance of that type back, as I don't think there is any way of the compiler knowing what the type should be?
public static <T> T create(final String className) {
try {
final Class<?> clazz = Class.forName(className);
//WARNING: Type safety: Unchecked cast from capture#2-of ? to T
return (T) create(clazz);
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static <T> T create(final Class<T> classToCreate) {
final Constructor<T> constructor;
try {
constructor = classToCreate.getDeclaredConstructor();
final T result = constructor.newInstance();
return result;
}
catch (Exception e) {
e.printStackTrace();
}
}
Thanks
I think that the first method should look something like this:
public static <T> T create(final String className, Class<T> ifaceClass)
throws ClassNotFoundException {
final Class<T> clazz = Class.forName(className).asSubclass(ifaceClass);
return create(clazz);
}
You cannot do an up-cast typecast using a type parameter ... without those pesky type-safety warnings.
By the way, if you ignore those warnings, the create method may create an instance of some class that isn't compatible with the actual type used by the caller. This is likely to lead to an unexpected ClassCastException later on; e.g. when the instance is assigned.
EDIT: @Pascal points out that we need to add a typecast to make this compile; i.e.
Class<T> clazz = (Class<T>) Class.forName(className).asSubclass(ifaceClass);
Unfortunately, we also need to add a @SuppressWarnings annotation.