2

У меня есть параметризованный интерфейс RestHandler.Java Generic For Parameterized Class: Unbounded Wildcards vs Raw Type

public interface RestHandler<T> { 
    blah blah blah... 
} 

И мне нужно создать класс из config, используя Class.forName. Теперь я придумал три версии, которые ВСЕ компилируются успешно.

Версия 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(); 
} 

Версия 2:

public static RestHandler<?> create(final String handlerImplFqcn) throws ClassNotFoundException, 
                    IllegalAccessException, 
                    InstantiationException { 
    @SuppressWarnings("rawtypes") 
    Class handlerClass = Class.forName(handlerImplFqcn); 
    return (RestHandler<?>) handlerClass.newInstance(); 
} 

Версия 3:

public static RestHandler<?> create(final String handlerImplFqcn) throws ClassNotFoundException, 
                    IllegalAccessException, 
                    InstantiationException { 
    Class<?> handlerClass = Class.forName(handlerImplFqcn); 
    return (RestHandler<?>) handlerClass.newInstance(); 
} 

Мой вопрос, почему все они работают, и которые можно было бы лучше практике?

+0

Мое личное предпочтение для первого примера, хотя вы не должны нуждаться в SuppressWarnings аннотации. Хотя вы должны отметить, что во всех этих примерах можно также исключить ClassCastException. – Dave

ответ

2

Version 1, переписан так:

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(); 
} 
+0

ли вы имеете в виду 'открытые статические > T создать (String handlerImplFqcn) бросает IllegalAccessException, InstantiationException, ClassNotFoundException { класса handlerClass = (класс ) Class.forName (handlerImplFqcn); return handlerClass.newInstance(); } ' –

0

Использование версии 1.

Version 2 использует сырые типы - избежать их, если это вообще возможно.

В версии 3 используется <?>, который также часто является анти-образцом, поскольку он редко достигает того, чего вы хотите достичь.