2013-06-06 12 views
10

Ich schreibe ein Programm, das Java-Reflektion verwendet (d. h. Class.forName()), um dynamisch Klasseninstanzen basierend auf Benutzereingaben zu erstellen. Eine Voraussetzung ist, dass die Instanz, die mein Programm erstellt, eine bestimmte definierte Klasse I, genannt SomeClass, erweitern muss. Meine Frage ist: zum Speichern dieser Klassenart, sollte ich beschränkte generische, Class<? extends SomeClass>, oder einfach unbegrenzte generische, Class? Ich fand einige Java-Bücher sagen, dass Klasse eine der guten Praktiken für die Verwendung von unbegrenzten Wildcard-generischen ist, aber ich frage mich, ob dies für die Situation in meinem Programm gelten.Java Generics - Klasse oder Klasse <? extends SomeClass>

Bitte zögern Sie nicht mich zu informieren, wenn Sie meine Frage nicht klar genug gefunden oder einige Informationen benötigt werden.

Antwort

16

Sie sollten Class<? extends SomeClass> verwenden, denn dafür gibt es Generika.

Zu dem Zeitpunkt, als Sie Class.forName aufrufen, überprüfen Sie, ob es SomeClass.class.isAssignableFrom der neuen Klasse ist. Andernfalls sollten Sie eine IllegalArgumentException oder ClassCastException werfen.

EDIT: Alternativ, Anruf asSubclass(SomeClass.class) wird dies für Sie tun.

Zum Beispiel:

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 ja, aber das ist nicht das, was OP angegeben. Er möchte, dass alle "SomeClass" erweitern. – wchargin

+3

Es wäre sauberer, einfach ['asSubclass'] zu verwenden (http: //docs.oracle.com/javase/7/docs/api/java/lang/Class.html#asSubclass \ (java.lang.Class \)) anstatt "isAssignableFrom" zu überprüfen und dann selbst eine Ausnahme auszulösen. –

+1

Es gibt auch immer noch keine Rechtfertigung für die ungeprüfte Besetzung - Ihre Hilfsmethode sollte einfach 'SomeClass' zurückgeben und nicht generisch sein. –

Verwandte Themen