2017-01-15 9 views
1

Also habe ich eine ArrayList von Objekten unbekannten Typs erweitern Entity (meine eigene Klasse; nicht zu verwechseln java.swing.text.html.parser.Entity) aus Gründen, die nichts damit zu tun haben dieses Problem.Hinzufügen eines Objekts der unbekannten Klasse zu ArrayList mit Reflexion

Dies ist in einer Klasse, die in ihrem Konstruktor einen String empfängt und es dem Feld entityClass zuweist.

Irgendwann bin ich die Ausführung des folgenden Code:

Class<?> clazz = Class.forName(this.entityClass); 
    Object newEntity = clazz.newInstance(); 

    listedEntities.add(newEntity); 

Natürlich ist dies nicht wie die Arraylist ist ein Objekt einer Klasse erwartet erstreckt Entity und NewEntity von Object ist. Also war es das erste Mal, Casting zu versuchen.

listedEntities.add(Class.forName(this.entityClass).cast(newEntity)); 

Auch funktioniert nicht. Und nachdem ich ein paar Minuten keine Antwort gefunden habe, schreibe ich hier.

Die Ausnahme:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The method add(capture#8-of ? extends Entity) in the type ArrayList<capture#8-of ? extends Entity> is not applicable for the arguments (capture#9-of ?) 
+2

Wie wäre es mit '' '' '' '' '' '' ' –

+0

Gibt es einen guten Grund, dass Sie' String' anstelle von 'Class' für' entityClass' verwenden? – Radiodef

Antwort

3

Eine einfache Lösung ist wie folgt:

  • ändern listedEntities zu ArrayList<Entity> statt ArrayList<? extends Entity>. Es sieht nicht so aus, als hätten Sie einen besonderen Grund, den Platzhalter zu verwenden, und der Platzhalter verhindert das Hinzufügen zu der Liste.

  • ändern Konstruktion dazu:

    Class<?> clazz = Class.forName(this.entityClass); 
    Entity newEntity = (Entity) clazz.newInstance(); 
    
    listedEntities.add(newEntity); 
    

Dies wird die Kompilierung-Fehler und es ist typsicher, dass lösen die explizite Umwandlung wird eine Ausnahme werfen, wenn irgendwie this.entityClass nicht einige Subtyp von Entity ist .

Eine vollständig generische Version, wie ich @RC glaube. Hinweise auf in den Kommentaren wäre wie folgt:

class Example<E extends Entity> { 
    private List<E> listedEntities = new ArrayList<>(); 
    private Class<E> entityClass; 

    Example(Class<E> entityClass) { 
     this.entityClass = entityClass; 
    } 

    void method() 
    throws IllegalAccessException, InstantiationException { 
     E newEntity = entityClass.newInstance(); 
     listedEntities.add(newEntity); 
    } 
} 

Das ist mehr "richtig"; Ob Sie jedoch etwas Ähnliches verwenden können, hängt von Ihren spezifischen Bedürfnissen ab.


Als eine Nebenbemerkung macht mir die Tatsache, dass Ihr Fehler als Ausnahme ausgelöst wird, ein wenig Sorgen. Sie sollten eine richtige IDE verwenden, die Kompilierungsfehler wie im Editor kennzeichnet, so dass Sie das Programm nicht ausführen müssen, um sie zu finden.

+0

In Bezug auf die Randnotiz: Ich benutze Eclipse Neon 2.0, aber die Ausnahme ist eine Ausnahme aufgrund der folgenden Einstiegspunkt - öffentliche statische void main (String [] args) {SwingUtilities.invokeLater (neue Runnable() {öffentliche void run() {new Primary();}}); } –

+0

Nun, das scheint gut zu sein. Ich denke, es sollte immer noch den Fehler während der Kompilierung anzeigen, aber leider weiß ich nicht genug über Eclipse, um zu sagen, warum das in diesem Fall nicht der Fall ist. – Radiodef

+0

In Bezug auf die vorgeschlagene Lösung: Es erfüllt nicht meine Bedürfnisse, eine ArrayList zu verwenden. Eigentlich war das die erste Version, bevor überhaupt Reflektionen verwendet wurden.Ich brauche Objekte der gleichen Klasse und diese Klasse muss die Entity erweitern. Die voll generische Version tut mir auch aus einem Grund nicht gut: Die Klasse, in der ich mich befinde, ist als Lister definiert und entspricht niemals der Klasse, die die ArrayList enthält. –

Verwandte Themen