# Klasse Dynamisch laden und zurückgeben



## planetenkiller (1. Aug 2007)

hallo,

Ich möchte eine Klasse zur Laufzeit laden eine Instanz erzeugen und diese Instanz zurückgeben. Leider verstehe ich das Reflection und Generics zeug nicht wirklich.

Es muss doch irgend eine Möglichkeit geben, das eine Funktion den Namen einer klasse bekommt, und dann eine Instanz zurückgibt?

folgendes habe ich:

```
public ??? getModul(String name) 
{
        Class klasse = Class.forName("packet.modules."+modul);
        // und jetzt?
}


// aufruf:
MeinModul klasse = getModul("MeinModul"); 
// so hatte ich das gedacht, bin mir aber nicht sicher ob es überhaubt so geht wie ich will
```


----------



## Yzebär (1. Aug 2007)

Probier es doch mal mit 
	
	
	
	





```
return klasse.newInstance();
```
 Rückgabewert ist dann ein Object, das du später in den Typ casten mußt, den du tatsächlich verwenden willst (zB in die Superklasse, von der deine dynamisch geladenen Klassen ableiten bzw. in das Interface, das alle dynamish geladenen Klassen implementieren). Wenn du keine Superklasse oder kein Interface benutzt, mußt du über Reflection auf Methoden und Member zugreifen.


----------



## thE_29 (1. Aug 2007)

Blöd ist halt wenn du keinen defaultConstructor hast!
Dann musst du dir die Konstruktoren zurückholen!


----------



## planetenkiller (1. Aug 2007)

Gibt es keine Möglichkeit, das mit Generics gleich auf die Klasse gecastet wird? Konstruktor hat keine Parameter.


----------



## SlaterB (1. Aug 2007)

es macht im Quellcode technisch gesehen keinen Sinn, generisch zu casten 
(diese beiden Begriffe schließen sich gegenseitig aus)
daher gehts auch nicht,


----------



## thE_29 (1. Aug 2007)

Außerdem wenn du den Klassenamen angibst, musst du auch eine Quelle angeben..

Von daher weißt du/kennst du die Klasse und daher ist das ja nicht mehr dynamisch casten!


----------



## planetenkiller (1. Aug 2007)

Das ist ja mega dof. Dann kann ich nicht mal eine Klasse zur laufzeit laden und dann via Variable/Referenz auf die Metoden zugreifen(Wobei die namen der Metoden nicht immer gleich sind).


----------



## SlaterB (1. Aug 2007)

poste doch mal Pseudo-Code, wie du dir den Zugriff vorstellst,
dann kann man
a) den Unsinn dieses Versuches zeigen (selbst wenn es gehen würde)
oder
b) die korrekte Syntax dafür andeuten


----------



## planetenkiller (1. Aug 2007)

Wie oben beschrieben, soll mir die Funktion ein Objekt(richtig gecastet natürlich, nicht ein Object) zurückgeben. Das ich dann ganz normal mit

klasse.funktion("parameter", "parameter1");

zugreifen kann. Mit Reflection und klasse.getClass().getMethod..... zugreifen finde ich dof, ich will mit der Klasse/Objekt richtig arbeiten.


----------



## SlaterB (1. Aug 2007)

also ganz normal casten, das geht natürlich

MeinModul klasse = (MeinModul) getModul("MeinModul");

denn wenn du normale Operationsaufrufe hinschreiben willst, musst du ja die Klasse kennen, 
also kannst du auch normal aus diese Klasse casten


----------



## planetenkiller (1. Aug 2007)

Den Namen der Klasse die ich laden will zb "MeinModul" ist in einer Variable gespeichert, und kann sich ändern. Daher kann ich die Rückgabe von getModul nicht casten?!


----------



## SlaterB (1. Aug 2007)

du drehst dich im Kreis: wenn du den Namen nicht hast, dann bringt dir auch das Casten nix (selbst wenn es ginge), 
denn dann ist eine Codezeile wie 


```
// aufruf: 
MeinModul klasse = getModul("MeinModul"); 
// so hatte ich das gedacht, ..
```
Quatsch

oder meinst du, dass zwar "MeinModul" in der Variablen steht,
du aber trotzdem auf MeinModul casten willst?
wie denn nun?


----------



## planetenkiller (1. Aug 2007)

ja, ich  habe in einer Variable den Namen einer Klasse. Eine Funktion soll eine Instanz der Klasse mit den Namen zurückgeben.

Verständlich genug?


----------



## SlaterB (1. Aug 2007)

soweit ist schon lange klar
Object o = getModul("MeinModul"); 
steht fest,

es ist nun die Frage, was du danach machen willst,
wenn du

MeinModul modul= irgendwie aus dem vorherigen;
modul.spezielleModulOperation();

ausführen willst, dann steht ja direkt im Quelltext MeinModul,
dann kannst du also auch 

MeinModul modul= (MeinModul) o;
modul.spezielleModulOperation();

schreiben, ein ganz normaler Cast,

-----

wenn du aber im Quelltext nicht MeinModul fest drinstehen hast,
dann macht es keinen Sinn irgendwas zu casten!


----------



## planetenkiller (1. Aug 2007)

ahaaaa, jetzt habe ich verstanden was du meinst. Da hast du recht das geht nicht.

Was ist, wenn ich eine Klasse Modul habe, gibt es eine Möglichkeit wärend der Laufzeit die klasse Modul per extends mit der rückgabe der getModul zu erweitern? Die Klasse java.lang.Class hat eine Methode asSubclass was sich danach anhört was ich will, aber ich verstehe leider nicht wie es geht(wenn überhaubt).


----------



## Wildcard (1. Aug 2007)

Man kann zur Laufzeit Interfaces implementieren mittels eines Proxy Objekts und einem InvocationHandler, nach dem bisherigen Verlauf dieses Threads zu Urteilen, würde ich dir aber davon abraten dich an so etwas zu wagen.


----------



## SlaterB (1. Aug 2007)

falls alle in Frage kommenden Klassen ein gemeinsames Interface Modul implementieren,
kann man auf dieses Interface casten


----------



## planetenkiller (1. Aug 2007)

Wenn ich aufs Interface caste, kann ich aber nur funktionen aufrufen, die im Interface definiert sind. Aber leider sind die funktionsnamen in jeder klasse anders. Ich glaube ich muss auf das Dynamische laden von Klassen(Modulen) verzichten und eine andere fest gecodete Lösung suchen.

Das mit dem Casten könnte ich lösen:

```
public ??? getModul(String name)
{
     Class cls = Class.forName("paket.modules."+name);
     Object obj = cls.newInstance();

     if(name.equals("Modul1"))
     {
           retrun (Modul1)obj;
     } else if(name.equals("Modul2"))
     {
           return (Modul2)obj;
     }
}
```
Nur der Return type müsste irgend wie Dynamisch sein, was aber, denke ich, nicht geht.


----------

