Methoden Kann man Klassen/Methoden aus Variablen heraus aufrufen?

nonickatall

Mitglied
Ich suche eine Lösung für folgendes Problem:

Angenommen ich möchte eine Methode in einer anderen Klasse aufrufen.

Dann mache ich das ja beispielsweise mit:
Java:
SMS.start(Parameter1);

Oder als Objekt mit

Java:
SMS sms1 = new SMS();
sms1.start(Parameter1);

Nun ermittle ich aber den Methodenaufruf, erst aus einer Tabelle, habe den Wert also in einer Variablen.
Also zum Beispiel:

Java:
String Aufruf = "SMS.start(Parameter1);";

Und will dann diesen Variablen Inhalt ganz normal als Methode aufrufen. Geht das irgendwie?

Hier, wenn es interessiert, warum ich das machen will..:

Vielen Dank im Voraus
 
Ja, das geht schon – ist aber in den meisten Fällen die schlechtere Variante.

In deinem Fall würde es ja am Ende nur dazu führen, dass der eigentliche Code als String in der Datenbank steht, und zB auch gar kein Typechecking o.ä. vor der Laufzeit stattfindet.

Vermutlich gäbe es für deinen Fall bessere Varianten, in Richtung eines Plugin-Systems. In der Datenbank stand sowas wie "Plugin XY soll ausgeführt werden", und das Programm reagiert dann entsprechend, dass kann man auch relativ abstrakt und gleichzeitig vernünftig programmiert halten.

Hängt ein bisschen davon ab, was deine Module alles können sollten bzw wie sie generell funktionieren sollen, aber im Allgemeinen lässt sich das so umsetzen. Je nachdem, was konkret gefordert ist, ist es u.U. auch sinnvoll, auf irgendein bestehendes Framework aufzusetzen.
 
Java:
import java.lang.reflect.Method;

class Kyle {

    public void Test(){System.out.println("invoking Test()");}

    public void Ronaldo(){System.out.println("invoking Ronaldo()");}

    public void MakeThis(){System.out.println("invoking MakeThis()");}



    public static void main(String[] args) throws Exception{

        Kyle k=new Kyle();

        String text = "Test";

        Class c=k.getClass();

        Method m=c.getDeclaredMethod(text);

        m.invoke(k);

    }

}

das ruft eine Methode über einen String auf
 
Für die Reflektion-API sehe ich hier keine Notwendigkeit. Ich würde auch davon abraten. Keine Typsicherheit, zu wenig Kontrolle usw. Am Ende musst du ja nur eine Bedingung auswerten: welche statische Methode welcher Klasse soll gestartet werden. Dann startest du diese einfach. Im simpelsten Fall ist das ein If-Else-Konstrukt. Die Parameter legst du am besten gesondert, z.B.: in einer anderen Spalte in der DB ab. So wie du das verwenden willst, müssen die Klasse und Methoden dem Programm sowieso bekannt sein.
 
Ja, das geht schon – ist aber in den meisten Fällen die schlechtere Variante.

In deinem Fall würde es ja am Ende nur dazu führen, dass der eigentliche Code als String in der Datenbank steht, und zB auch gar kein Typechecking o.ä. vor der Laufzeit stattfindet.

Vermutlich gäbe es für deinen Fall bessere Varianten, in Richtung eines Plugin-Systems. In der Datenbank stand sowas wie "Plugin XY soll ausgeführt werden", und das Programm reagiert dann entsprechend, dass kann man auch relativ abstrakt und gleichzeitig vernünftig programmiert halten.

Hängt ein bisschen davon ab, was deine Module alles können sollten bzw wie sie generell funktionieren sollen, aber im Allgemeinen lässt sich das so umsetzen. Je nachdem, was konkret gefordert ist, ist es u.U. auch sinnvoll, auf irgendein bestehendes Framework aufzusetzen.
Das ist richtig Typechecking wäre damit dann schlecht möglich. Das wäre nicht so wichtig weil das nicht soviel ist und das sich auch nicht ständig ändert.

Was meinst du mit einem Plugin System? Und wie könnte ich das realisieren?

Die Module sind halt im wesentlichen ein SMS Modul zur Kommunikation, das nur auf einem Gerät ausgeführt wird. Dann entsprechende GPIO Module die natürlich abhängig von den angeschlossenen Geräten sind. GUI Modul das natürlich nur an dem Gerät ausgeführt wird wo auch ein Bildschirm hängt. Und andere Kleinigkeiten.
 
Also erst einmal ist die Frage, ob Du ein Plugin System brauchst. Das ist dann sinnvoll, wenn Du Plugins dynamisch dazu oder weg nehmen willst. Also z.B. schreibst Du ein Produkt und ich erweitere es dann durch ein eigenes Plugin...

Generell reicht es, dass Du irgendwas baust, dass mögliche Aufrufe verwaltet. Das kann schon eine einfache Map sein, z.B. eine Map<String, Consumer<SomeData>> (Sprich: Nutz den functional Part , den Java mit Java 8 bekommen hat, Namespace java.util.function)

SomeData kann dann eine Klasse sein, die Daten enthält, die notwendig sind:
- Das können z.B. wichtige Referenzen auf andere Instanzen sein, die dann verwendet werden können sollen.
- Das kann aber auch eine Art Konfiguration sein. Du hattest da ja sowas wie Parameter vorgesehen. Das könnten also z.B. einfache Key/Value Paare sein.

Und in deinen Klassen kannst Du dann beliebige Methoden haben, die halt SomeData als Parameter entgegen nehmen und nichts zurück geben (*).

Dann musst Du bei der Initialisierung nur die Map füllen. Und wenn dann aus der Datenbank ein Task gelesen wird, dann schaust du in der map nach und rufst den Consumer auf.

(Statt eines Consumer, der nichts zurück gibt, kannst Du auch eine Function nutzen - dann hast Du noch einen Returntyp Deiner Wahl.)

Wenn es das Plugin System sein soll, dann wäre halt mein Ansatz, dass man die sogenannten Service Provider verwendet. Das ist eine Methodik, die seit Java 6 vorhanden ist und z.B. von JDBC verwendet wird. Ein jar File kann dann angeben, dass es einen Service anbietet und darauf kann dann zugegriffen werden ohne viel eigenen Code. Siehe dazu z.B. https://www.baeldung.com/java-spi

Und auch hier noch einmal mein Ratschlag: Fang am Anfang mit weniger Features an und bau ein erstes Produkt. Das kannst Du dann nach und nach erweitern. Ansonsten fürchte ich, dass Du die Erfahrung machst, die viele am Anfang machen dürfen: Es wird an zu vielen Stellen gleichzeigt gebastelt und dann ist relativ schnell der Überblick weg, die Erfolgserlebnisse bleiben aus und das Projekt landet in der Ecke ... Aber da muss ich mich nicht wiederholen - das hatte ich Dir im anderen Thread schon als Ratschlag gegeben, daher vertiefe ich das auch nicht erst weiter.
 
So, ich habe das ganze noch mal überdacht, und vor allem das Thema Typechecking und dass ich im Grunde genommen gar nicht so viele Module habe, hat mich überzeugt von diesem Ansatz Abstand zu nehmen und das lieber mit entsprechenden if Statements zu lösen.

Danke an alle
 

Zurück
Oben