Class[] genauer spezifizieren

  • Themenstarter Themenstarter Guest
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Hallo,

in meinem Programm hab ich in der Klasse ClassIdentifier eine Methode mit folgendem Profil:


Code:
public static void Class[] getClasses(Class superClass)

Diese Methode durchsucht ein Verzichnis nach Klassen die Unterklassen von superClass sind. Das funktioniert auch einwandfrei, ich hab nur ein Problem damit, das ich am folgenden Beispiel erklären will.

Es gibt die abstrakte Klasse A

Code:
public abstract class A
{
    public abstract void doSomething();
}

Im Programm lasse ich mir nun mit der oben genannten Methode alle Klassen suchen die von A erben und will dann deren Methode doSomething() ausführen.


Code:
Class[] classes = ClassIdentifier.getClasses(A.getClass());
    
for (int i = 0; i < classes.length; i++)
{			
    ((A)classes[i].newInstance()).doSomething();
}

Das klappt auch, aber kann ich mir den Cast irgenwie sparen, kann ich dem Programm irgendwie verständlich machen, dass das Class[] das als Rückgabewert geliefert nur Class-Objekte enthählt deren Instanzen von A abgeleitet sind? Vielleicht mit Generik etc?

Ich hoffe die Frage ist verständlich :lol:

mfg Thomas
 
Hm, vielleicht sowas:
Code:
Class<? extends A>[] classes = ClassIdentifier.getClasses( A.class );

Die "getClasses"-Methode muss dann auch entsprechend abgeändert werden (und da man keine generischen Arrays erzeugen kann, wird immer irgendwo ein Cast herumliegen. Wenigstens passt der Cast besser in getClasses).
 
Danke, das hat mit weitergeholfen. Ich hab die Methode in der Klasse ClassIdentifier jetzt so deklariert:

Code:
public static <T> Class<? extends T>[] getClasses(Class<? extends T> pattern)
Damit kann ich mir den Cast sparen und der Code im Programm sieht so aus:


Code:
Class[] classes = ClassIdentifier.getClasses(A.getClass()); 
    
for (int i = 0; i < classes.length; i++) 
{       
    Class<? extends A>[] classes = identifier.getClasses(A.class);   
    classes[i].newInstance().doSomething(); 
}


Das funktioniert so und ich denke mal, dass das so sauberer ist als vorher. Der Cast wird jetzt, wie du schon gesagt hast, in der Methode getClasses gemacht und zwar folgendermaßen:

Code:
public static <T> Class<? extends T>[] getClasses(Class<? extends T> pattern)
{
    ArrayList<Class<? extends T>> matches = new ArrayList<Class<? extends T>>();

      /*
       *    Hier steht der Code um die Liste zu füllen
       */
    return matches.toArray(new Class[0]);
}

Der Cast findet automatisch in der letzten Zeile statt, die stört mich aber noch. Sie wird mit folgender Warnung kompiliert:


Code:
Type safety: The expression of type Class[] needs unchecked conversion to conform to Class<? extends T>[]

Sehe ich das richtig, dass ich das nicht ändern kann, weil ich kein Class<? extends T>[] erzeugen kann?
 
hm also ganz ohne casts kannst du das schon machen und zwar mittels der Klasse Class. Du kannst dort objekte dynamisch erzeugen (einfach den String für den klassennamen nehmen) mit

Code:
Class test = Class.forName("Superklasse"); 
Object testObject = test.newInstance();

das macht dir dynamisch ein object daraus. du kannst von der klasse auch die methoden aufrufen lassen (auch dynamisch ohne casts) usw. brauchst dich nur kurz einlesen dann verstehst schon was ich meine 😉
 
Zu Natorion:
So wie ich den Gast verstanden habe, möchte er aber kein Objekt, sondern ein ganz bestimmter Typ von Instancen. Das wäre dann was anderes, als du vorschlägst?
 
ne meiner meinung nach will er einfach nur die abgeleiteten klassen von A haben und bei jeder dieser klasse eine instanz erzeugen und dort die methode doSomething() aufrufen und das am besten ohne casts (damits dynamisch ist und man keine source code änderungen machen muss).

Code:
public static void Class[] getClasses(Class superClass) {
    return superClass.getClasses;
}

.....
......
.....

Class[] classes = ClassIdentifier.getClasses(Class.forName("A"));
    
for (int i = 0; i < classes.length; i++) 
{          
    Method currentMethod = classes[i].getMethod("doSomething", null);
    currentMethod.invoke(classes[i].newInstance(), null);

}

jo das wars denk ich 😉
[/code]
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben