2013-06-06 4 views
10

Я пишу программу, которая будет использовать отражение Java (т. е. Class.forName()) для динамического создания экземпляра класса на основе ввода пользователя. Одним из требований является то, что экземпляр, созданный моей программой, должен расширять один определенный класс I, называемый SomeClass. Мой вопрос: для хранения этого типа класса я должен использовать ограниченный родовой, Class<? extends SomeClass> или просто неограниченный общий, Class? Я обнаружил, что некоторые Java-книги говорят, что Class является одной из хороших практик использования неограниченного подстановочного знака, но мне интересно, относится ли это к ситуации в моей программе.Java Generics - класс или класс <? extends SomeClass>

Пожалуйста, не стесняйтесь, дайте мне знать, если вы нашли мой вопрос, недостаточно ясный или нужна некоторая информация.

ответ

16

Вы должны использовать Class<? extends SomeClass>, потому что для этого нужны дженерики.

В то время, когда вы вызываете Class.forName, проверьте, есть ли это SomeClass.class.isAssignableFrom новый класс. В противном случае вы должны выбросить IllegalArgumentException или ClassCastException.

EDIT: В противном случае вызов asSubclass(SomeClass.class) сделает это за вас.

Например:

public SomeClass instantiate(String name) 
    throws ClassNotFoundException, InstantiationException, IllegalAccessException { 

    Class<?> raw = Class.forName(name); 

    //throws ClassCastException if wrong 
    Class<? extends SomeClass> generic = raw.asSubclass(SomeClass.class); 

    // do what you want with `generic` 

    return generic.newInstance(); 
} 
+0

@Vulcan да, но это не то, что OP указано. Он хочет, чтобы все они расширили «SomeClass». – wchargin

+3

Было бы просто использовать ['asSubclass'] (http: //docs.oracle.com/javase/7/docs/api/java/lang/Class.html#asSubclass \ (java.lang.Class \)) вместо проверки 'isAssignableFrom', а затем выбрасывает исключение самостоятельно. –

+1

Кроме того, все еще нет оправдания для неконтролируемого актера - ваш вспомогательный метод должен просто вернуть 'SomeClass' и не быть общим. –

Смежные вопросы