I have a parameterized interface RestHandler.
public interface RestHandler<T> {
blah blah blah...
}
And I need to create a class from config using Class.forName. Now I come up with three version , which ALL compiles successfully.
Version 1:
@SuppressWarnings("unchecked")
public static <T> RestHandler<T> create(final String handlerImplFqcn) throws ClassNotFoundException,
IllegalAccessException,
InstantiationException {
Class<?> handlerClass = Class.forName(handlerImplFqcn);
return (RestHandler<T>) handlerClass.newInstance();
}
Version 2:
public static RestHandler<?> create(final String handlerImplFqcn) throws ClassNotFoundException,
IllegalAccessException,
InstantiationException {
@SuppressWarnings("rawtypes")
Class handlerClass = Class.forName(handlerImplFqcn);
return (RestHandler<?>) handlerClass.newInstance();
}
Version 3:
public static RestHandler<?> create(final String handlerImplFqcn) throws ClassNotFoundException,
IllegalAccessException,
InstantiationException {
Class<?> handlerClass = Class.forName(handlerImplFqcn);
return (RestHandler<?>) handlerClass.newInstance();
}
My question is , why they ALL work and which one would be best practice ?
Version 1, re-written to this:
public static <T extends RestHandler<?>> RestHandler<T> create(final String handlerImplFqcn) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ClassCastException {
Class<T> handlerClass = (Class<T>) Class.forName(handlerImplFqcn);
return (RestHandler<T>) handlerClass.newInstance();
}