Funktionszeiger in Java

Lesezeit: 5 Minuten

Dies mag etwas Alltägliches und Triviales sein, aber ich scheine Schwierigkeiten zu haben, eine konkrete Antwort zu finden. In C# gibt es ein Konzept von Delegaten, das sich stark an die Idee von Funktionszeigern aus C++ anlehnt. Gibt es eine ähnliche Funktionalität in Java? Angesichts der Tatsache, dass Hinweise etwas fehlen, was ist der beste Weg, dies zu tun? Und um das klarzustellen, wir reden hier erstklassig.

  • Ich bin nur neugierig, warum Sie dies wollen, wo Listener oder andere OOP-Konstrukte die gleiche Aufgabe erledigen würden, während sie ihre Objektnatur beibehalten. Ich meine, ich verstehe die Notwendigkeit der Funktionalität, die das Konzept bietet, nur dass sie mit einem einfachen Objekt erreicht werden kann. Es sei denn, mir fehlt natürlich etwas, daher meine Frage! 🙂

    – Neutopisch

    2. Juli 09 um 10:58 Uhr

  • Java 8 hat Lambda-Ausdrücke: docs.oracle.com/javase/tutorial/java/javaOO/… Vielleicht möchten Sie das überprüfen. Nicht ganz ein Funktionszeiger, aber vielleicht noch nützlicher.

    – FrustriertMitFormularDesigner

    6. Mai 14 um 19:51 Uhr


  • Java 8-Methodenreferenzen sind genau das, wonach Sie fragen.

    – Stefan

    5. Juni 14 um 08:23 Uhr

  • Java 8 Methodenreferenzen ist genau das, wonach Sie fragen. this::myMethod ist semantisch dasselbe wie das Erstellen eines Lambda paramA, paramB -> this.myMethod(paramA, paramB).

    – Stefan

    5. Juni 14 um 8:30 Uhr


  • mögliches Duplikat von Was ist der nächste Ersatz für einen Funktionszeiger in Java?

    – nawfal

    5. Juli 14 um 7:19 Uhr

Funktionszeiger in Java
Michael Borgwart

Das Java-Idiom für funktionszeigerähnliche Funktionalität ist eine anonyme Klasse, die eine Schnittstelle implementiert, z

Collections.sort(list, new Comparator<MyClass>(){
    public int compare(MyClass a, MyClass b)
    {
        // compare objects
    }
});

Aktualisieren: Das Obige ist in Java-Versionen vor Java 8 erforderlich. Jetzt haben wir viel schönere Alternativen, nämlich Lambdas:

list.sort((a, b) -> a.isGreaterThan(b));

und Methodenreferenzen:

list.sort(MyClass::isGreaterThan);

  • @Raedwald C++ hat Funktoren und C++0x hat Closures und Lambdas, die auf Funktoren aufbauen. Das hat es sogar std::bind, die Parameter an Funktionen bindet und ein aufrufbares Objekt zurückgibt. Ich kann C aus diesen Gründen nicht verteidigen, aber C++ wirklich ist besser als Java dafür.

    – zneak

    2. März 11 um 4:48 Uhr


  • @zneak, @Raedwald: Sie können dies in C tun, indem Sie einen Zeiger auf Benutzerdaten übergeben (zB: struct). (und kann es mit jeder neuen Callback-Indirektion kapseln) Es ist eigentlich ziemlich sauber.

    – Briese

    10. Juni 11 um 14:06 Uhr

  • Ja, ich werde tatsächlich jeden Tag Crufty-Funktionszeiger über Crufty-Wrapper-Klassen nehmen

    – BT

    17. Mai ’12 um 2:26 Uhr

  • @Raedwald, dafür sind Delegierte in C# da! Sie sind saubere, typsichere Funktionszeiger.

    – devinbost

    9. Mai 14 um 6:51 Uhr

  • Java 8 hat dafür eine bessere Syntax.

    – Thorbjørn Ravn Andersen

    25. Juni 14 um 9:42 Uhr

Funktionszeiger in Java
raupach

Sie können einen Funktionszeiger durch eine Schnittstelle ersetzen. Angenommen, Sie möchten eine Sammlung durchlaufen und mit jedem Element etwas tun.

public interface IFunction {
  public void execute(Object o);
}

Dies ist die Schnittstelle, die wir beispielsweise an CollectionUtils2.doFunc(Collection c, IFunction f) übergeben könnten.

public static void doFunc(Collection c, IFunction f) {
   for (Object o : c) {
      f.execute(o);
   }
}

Als Beispiel sagen wir, wir haben eine Sammlung von Zahlen und Sie möchten zu jedem Element 1 hinzufügen.

CollectionUtils2.doFunc(List numbers, new IFunction() {
    public void execute(Object o) {
       Integer anInt = (Integer) o;
       anInt++;
    }
});

1643869027 491 Funktionszeiger in Java
zoquete

Sie können die Reflexion dazu verwenden.

Übergeben Sie als Parameter das Objekt und den Methodennamen (als Zeichenfolge) und rufen Sie dann die Methode auf. Beispielsweise:

Object methodCaller(Object theObject, String methodName) {
   return theObject.getClass().getMethod(methodName).invoke(theObject);
   // Catch the exceptions
}

Und dann verwenden Sie es wie in:

String theDescription = methodCaller(object1, "toString");
Class theClass = methodCaller(object2, "getClass");

Überprüfen Sie natürlich alle Ausnahmen und fügen Sie die erforderlichen Umwandlungen hinzu.

  • Reflexion ist nicht die richtige Antwort auf irgendetwas außer “Wie schreibe ich langsamen zwielichtigen Java-Code” 😀

    – Jay

    5. August 13 um 12:34 Uhr

  • Es mag “hässlich” und langsam sein, aber ich glaube, dass die Reflexion es ermöglicht, Dinge zu tun, die die schnittstellenbasierte Lösung in der akzeptierten Antwort nicht kann (es sei denn, ich irre mich), nämlich verschiedene Methoden desselben Objekts innerhalb desselben Codes aufzurufen Portion.

    – Eusebius

    9. April 14 um 6:50 Uhr

  • @zoquete.. Ich habe diesen Beitrag durchgesehen und hatte Zweifel.. Wenn ich also in Ihrem Ansatz auf die Variable “theDescription” zugreife, wird die Funktion jedes Mal aufgerufen, wenn auf die Variable zugegriffen wird.

    – karthik27

    16. April 14 um 18:48 Uhr

1643869028 694 Funktionszeiger in Java
jwoolard

Nein, Funktionen sind keine erstklassigen Objekte in Java. Sie können dasselbe tun, indem Sie eine Handler-Klasse implementieren – so werden Callbacks in Swing usw. implementiert.

Es gibt jedoch Vorschläge für Schließungen (der offizielle Name für das, worüber Sie sprechen) in zukünftigen Versionen von Java – Javawelt hat einen interessanten Artikel.

Das erinnert an Steve Yegges Hinrichtung im Reich der Substantive. Es besagt im Grunde, dass Java für jede Aktion ein Objekt benötigt und daher keine „Nur-Verb“-Entitäten wie Funktionszeiger hat.

Um eine ähnliche Funktionalität zu erreichen, könnten Sie anonyme innere Klassen verwenden.

Wenn Sie eine Schnittstelle definieren würden Foo:

interface Foo {
    Object myFunc(Object arg);
}

Erstellen Sie eine Methode bar die einen ‘Funktionszeiger’ als Argument erhält:

public void bar(Foo foo) {
    // .....
    Object object = foo.myFunc(argValue);
    // .....
}

Rufen Sie die Methode schließlich wie folgt auf:

bar(new Foo() {
    public Object myFunc(Object arg) {
        // Function code.
    }
}

Funktionszeiger in Java
Alexander Ach

Java8 hat Lambdas und eingeführt Methodenreferenzen. Wenn Ihre Funktion also mit a übereinstimmt funktionale Schnittstelle (Sie können Ihre eigene erstellen) Sie können in diesem Fall eine Methodenreferenz verwenden.

Java bietet eine Reihe von gemeinsame Funktionsschnittstellen. während Sie Folgendes tun könnten:

public class Test {
   public void test1(Integer i) {}
   public void test2(Integer i) {}
   public void consumer(Consumer<Integer> a) {
     a.accept(10);
   }
   public void provideConsumer() {
     consumer(this::test1);   // method reference
     consumer(x -> test2(x)); // lambda
   }
}

  • gibt es das Konzept eines alias: z.B public List<T> collect(T t) = Collections::collect

    – WestCoastProjects

    5. Januar 20 um 19:50 Uhr

  • @javadba soweit ich weiß nicht.

    – Alexander Ach

    5. Januar 20 um 20:57 Uhr

.

751570cookie-checkFunktionszeiger in Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy