Variablen Java Function Pointer

Survari

Mitglied
Hi! Ich habe ein kleines Problem! Undzwar versuche ich in Java eine klasse zu erstellen, die es möglich macht Funktionen einzuspeichern. Ich benutze sie um bestimmte Befehle bei einer Eingabe auszuführen. In C und C++ war dies mit Function-Pointer möglich. Diese haben dann als Variable gedient und bei der verwendung haben sie die Funktion die sie beinhaltet haben durchgeführt:
void (*foo)(int); // foo erstellen
foo = &funktion; // foo funktion() zuweisen
foo(); // foo führt funktion(); aus​
(Hab die Code-Funktion nicht gefunden 😵)

In Java bin ich da an meine grenzen gestoßen. Da ich aber keine Komplette Klasse für jeden Befehl erstellen (zumindest nicht immer den gleichen Code der Klasse wiederholen) will und sicher andere das Problem auch hatten, muss es doch eine ähnliche Funtkion in Java geben?

(Mein erster Beitrag in dem Forum hier, bitte seid mir nicht zu Böse wenn ich hier etwas falsch verstehe 😉 )
 
Ich verstehe den Sinn dahinter nicht so ganz. Muss dazu sagen, dass ich auch nie wirklich mit C oder C++ warm geworden bin...
Willst du einfach von dir geschriebene Methoden von überall ausführen?
 
Nein, ich möchte... Ich schick mal ein Beispiel:

Command f = new Command();
f.setName("Test");
f.setFunction(machTest("Argumente"));

Das meine ich. In der setFunction Methode wird dann halt eine Funktion gespeichert, die dann mit f.runFunktion(); ausgeführt werden kann. Verstehst du das? Sonnst kannst du dir ja mal die Function-Pointer von C anschauen. Die "speichern" eine Funktion in sich und rufen diese nach Bedürfnis wieder auf.

Tatsächlich kenne ich in Java kein Beispiel das irgendwo in der API oder in Bibliotheken verbaut wurde....
 
Ich denke ich verstehe. Also, man könnte sowas per Relection erreichen. Aaaber, dazu sei gesagt, dass Reflection schon sehr bedacht eingesetzt werden sollte. Es ist schon sehr mächtig. Meistens ist man mit anderen Lösungswegen besser unterwegs.
Mit Reflection lassen sich z.B. Klassen, Methoden, Attribute(Felder) als Objekte behandeln. Mann kann sich etwa von einer Methode ein Objekt vom Typ java.lang.reflect.Method besorgen und könnte diese "Methode" auch ausführen.
 
In Java gibt es sowas nicht und das aus gutem Grund. In Java musst du eine eigene Klasse dafür definieren; für dein Beispiel ließe sich auch Runnable benutzen:

Java:
class Command {
   private Runnable fn;
   public void setFunction(Runnable function) {
       this.fn = Objects.requireNonNull(function);
   }
   public void runFunction
}

Java:
Command f = new Command();
f.setFunction(new Runnable() {
    @Override public void run() {
        machTest("Argumente");
    }
}

Ab Java 8 kannst du mit Lambdas eine änliche Syntax wie in deinem Beispiel erreichen:

Java:
Command f = new Command();
f.setFunction(() -> machTest("Argumente"));

Und seit Java 8 gibt es auch sogenannte Functionsreferenzen. Hier kommst du aber um ein eigenes Interface nicht drum herum, weil Java zur Compiletime auch die Funktionssignatur prüft (was ja in C/C++ nicht der Fall ist):

Java:
interface CommandFunction {
    public void run(String arg);
}

Java:
Command f = new Command();
f.setFunction(System.out::println);

-----

In eher funktionalen Sprachen, welche auch auf der JVM laufen (bspw. Scala, Groovy, Kotlin) gibt es den Ansatz, mehrere Generic-Interfaces dafür zu nutzen:

Java:
interface Function1<R,A> {
    public R run(<? extends A> arg1);
}
interface Function2<R,A,B> {
    public R run(<? extends A> arg1, <? extends B> arg2);
}
interface Function3<R,A,B,C> {
    public R run(<? extends A> arg1, <? extends B> arg2, <? extends C> arg3);
}
interface Function4<R,A,B,C,D> {
    public R run(<? extends A> arg1, <? extends B> arg2, <? extends C> arg3, <? extends D> arg4);
}
// usw.

Aber auch damit wird die Methodensignatur zur Compilezeit forciert.

EDIT:
Das ist keine Reflection. Ja, mit Reflection ginge das, ist aber äußerst unkomfortabel und bietet nicht die Typsicherheit von Lambdas.

P.S.: Es sei gesagt, dass solche Konstrukte nicht notwendig sind, wenn man eine Saubere Anwendungsarchitektur hat. @TE: Du kannst dein Problem wahrscheinlich auch anders lösen.
 

Neue Themen


Zurück
Oben