Wie kann ich eine anonyme Funktion in Java schreiben?

Lesezeit: 6 Minuten

Benutzer-Avatar
Aaron

Ist es überhaupt möglich?

  • Beachten Sie, dass dies jetzt in Java 8 möglich ist – siehe die Antwort zu Lambda-Ausdrücken von Mark Rotteveel unten.

    – Josiah Yoder

    13. Januar 2015 um 21:06 Uhr


Benutzer-Avatar
Chris

wenn Sie eine anonyme Funktion meinen, und eine Version von Java vor Java 8 verwenden, dann mit einem Wort, nein. (Lesen Sie mehr über Lambda-Ausdrücke, wenn Sie Java 8+ verwenden)

Sie können jedoch eine Schnittstelle mit einer Funktion wie dieser implementieren:

Comparator<String> c = new Comparator<String>() {
    int compare(String s, String s2) { ... }
};

und Sie können dies mit inneren Klassen verwenden, um eine fast anonyme Funktion zu erhalten 🙂

  • Noch nicht. In Java 7 wird es möglich sein: stackoverflow.com/questions/233579/closures-in-java-7

    – Ilja Boyandin

    3. Mai 2010 um 7:58 Uhr

  • In der Zwischenzeit können während des Wartens auf JDK7 anonyme Methoden in einem OO-Kontext mit emuliert werden en.wikipedia.org/wiki/Command_pattern

    – gpampara

    3. Mai 2010 um 11:26 Uhr

  • closeded hat es nicht in Java 7 geschafft.

    – Thorbjørn Ravn Andersen

    6. Juli 2011 um 21:55 Uhr

  • Ich denke, Sie sollten Ihre Antwort ändern, da wir mit Java 8 eine anonyme Funktion haben.

    – Node.JS

    23. April 2014 um 13:42 Uhr

Benutzer-Avatar
polygenelubricants

Hier ist ein Beispiel für eine anonyme innere Klasse.

System.out.println(new Object() {
    @Override public String toString() {
        return "Hello world!";
    }
}); // prints "Hello world!"

Dies ist so wie es ist nicht sehr nützlich, aber es zeigt, wie man eine Instanz einer anonymen inneren Klasse that extends Object und @Override es ist toString() Methode.

Siehe auch


Anonyme innere Klassen sind sehr praktisch, wenn Sie eine implementieren müssen interface die möglicherweise nicht in hohem Maße wiederverwendbar ist (und es daher nicht wert ist, in eine eigene benannte Klasse umgestaltet zu werden). Ein lehrreiches Beispiel ist die Verwendung einer benutzerdefinierten java.util.Comparator<T> zum Sortieren.

Hier ist ein Beispiel, wie Sie a sortieren können String[] bezogen auf String.length().

import java.util.*;
//...

String[] arr = { "xxx", "cd", "ab", "z" };
Arrays.sort(arr, new Comparator<String>() {
    @Override public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }           
});
System.out.println(Arrays.toString(arr));
// prints "[z, cd, ab, xxx]"

Beachten Sie den hier verwendeten Vergleich-durch-Subtraktions-Trick. Es sollte gesagt werden, dass diese Technik im Allgemeinen kaputt ist: Sie ist nur anwendbar, wenn Sie garantieren können, dass sie nicht überläuft (wie dies der Fall ist bei String Längen).

Siehe auch

  • Java Integer: Was ist ein schneller Vergleich oder eine schnellere Subtraktion?
    • Vergleich-durch-Subtraktion ist gebrochen Im Algemeinen
  • Erstellen Sie einen sortierten Hash in Java mit einem benutzerdefinierten Komparator
  • Wie werden anonyme (innere) Klassen in Java verwendet?

  • Die Mehrheit der anderen Vorkommen kann als gefunden werden EventListener (Unter-)Implementierungen in der durchschnittlichen Swing-Anwendung.

    – BalusC

    2. Mai 2010 um 23:47 Uhr


  • @BalusC: Link zur Frage “Wie werden sie verwendet” hinzugefügt

    – polygenelubricants

    3. Mai 2010 um 0:25 Uhr

  • @BalusC: Stackoverflow hat kürzlich die hinzugefügt Linked Seitenleiste, also tue ich mein Bestes, um davon Gebrauch zu machen.

    – polygenelubricants

    3. Mai 2010 um 0:42 Uhr

Mit der Einführung des Lambda-Ausdrucks in Java 8 können Sie jetzt anonyme Methoden verwenden.

Sagen Sie, ich habe eine Klasse Alpha und ich möchte filtern Alphas unter einer bestimmten Bedingung. Dazu können Sie eine verwenden Predicate<Alpha>. Dies ist eine funktionale Schnittstelle, die eine Methode hat test das akzeptiert ein Alpha und gibt a zurück boolean.

Angenommen, die Filtermethode hat diese Signatur:

List<Alpha> filter(Predicate<Alpha> filterPredicate)

Mit der alten Lösung für anonyme Klassen müssten Sie Folgendes tun:

filter(new Predicate<Alpha>() {
   boolean test(Alpha alpha) {
      return alpha.centauri > 1;
   }
});

Mit den Java 8-Lambdas können Sie Folgendes tun:

filter(alpha -> alpha.centauri > 1);

Nähere Informationen finden Sie unter Tutorial zu Lambda-Ausdrücken

Anonyme innere Klassen, die die Schnittstelle eines vorhandenen Typs implementieren oder erweitern, wurden in anderen Antworten durchgeführt, obwohl es erwähnenswert ist, dass mehrere Methoden implementiert werden können (häufig beispielsweise mit Ereignissen im JavaBean-Stil).

Ein wenig bekanntes Merkmal ist, dass anonyme innere Klassen zwar keinen Namen, aber einen Typ haben. Der Schnittstelle können neue Methoden hinzugefügt werden. Diese Methoden können nur in begrenzten Fällen aufgerufen werden. Hauptsächlich direkt an der new Ausdruck selbst und innerhalb der Klasse (einschließlich Instanzinitialisierern). Es könnte Anfänger verwirren, aber es kann für die Rekursion “interessant” sein.

private static String pretty(Node node) {
    return "Node: " + new Object() {
        String print(Node cur) {
            return cur.isTerminal() ?
                cur.name() :
                ("("+print(cur.left())+":"+print(cur.right())+")");
        }
    }.print(node);
}

(Ich habe dies ursprünglich mit geschrieben node statt cur in dem print Methode. Sagen Sie NEIN zum “impliziten Erfassen”. final„Einheimische?)

Benutzer-Avatar
Muair

Ja, wenn Sie Java 8 oder höher verwenden. Java 8 ermöglicht es, anonyme Funktionen zu definieren, was in früheren Versionen unmöglich war.

Nehmen wir ein Beispiel aus Java-Dokumente um zu erfahren, wie wir anonyme Funktionen und Klassen deklarieren können

Das folgende Beispiel, HelloWorldAnonymousClasses, verwendet anonyme Klassen in den Initialisierungsanweisungen der lokalen Variablen frenchGreeting und spanishGreeting, aber verwendet eine lokale Klasse für die Initialisierung der Variablen englishGreeting:

public class HelloWorldAnonymousClasses {
  
    interface HelloWorld {
        public void greet();
        public void greetSomeone(String someone);
    }
  
    public void sayHello() {
        
        class EnglishGreeting implements HelloWorld {
            String name = "world";
            public void greet() {
                greetSomeone("world");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hello " + name);
            }
        }
      
        HelloWorld englishGreeting = new EnglishGreeting();
        
        HelloWorld frenchGreeting = new HelloWorld() {
            String name = "tout le monde";
            public void greet() {
                greetSomeone("tout le monde");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Salut " + name);
            }
        };
        
        HelloWorld spanishGreeting = new HelloWorld() {
            String name = "mundo";
            public void greet() {
                greetSomeone("mundo");
            }
            public void greetSomeone(String someone) {
                name = someone;
                System.out.println("Hola, " + name);
            }
        };
        englishGreeting.greet();
        frenchGreeting.greetSomeone("Fred");
        spanishGreeting.greet();
    }

    public static void main(String... args) {
        HelloWorldAnonymousClasses myApp =
            new HelloWorldAnonymousClasses();
        myApp.sayHello();
    }            
}

Syntax anonymer Klassen

Betrachten Sie die Instanziierung des Objekts frenchGreeting:

    HelloWorld frenchGreeting = new HelloWorld() {
        String name = "tout le monde";
        public void greet() {
            greetSomeone("tout le monde");
        }
        public void greetSomeone(String someone) {
            name = someone;
            System.out.println("Salut " + name);
        }
    };

Der anonyme Klassenausdruck besteht aus Folgendem:

  • Das new Operator

  • Der Name einer zu implementierenden Schnittstelle oder einer zu erweiternden Klasse. In diesem Beispiel implementiert die anonyme Klasse die Schnittstelle HelloWorld.

  • Klammern, die die Argumente für einen Konstruktor enthalten, genau wie ein normaler Ausdruck zum Erstellen einer Klasseninstanz. Hinweis: Wenn Sie eine Schnittstelle implementieren, gibt es keinen Konstruktor, daher verwenden Sie wie in diesem Beispiel ein leeres Klammerpaar.

  • Ein Körper, der ein Klassendeklarationskörper ist. Genauer gesagt sind im Hauptteil Methodendeklarationen zulässig, Anweisungen jedoch nicht.

Benutzer-Avatar
michal.jakubeczy

Sie können auch verwenden Consumer und BiConsumer Geben Sie an, wie viele Parameter Sie benötigen. Consumer akzeptiert einen Parameter, BiConsumer akzeptiert zwei.

public void myMethod() {
  // you can declare it here
  Consumer<String> myAnonymousMethod = s -> {
    System.out.println(s);
  };

  // you can call it here
  muAnonymousMethod.apply("Hello World");
}

1270640cookie-checkWie kann ich eine anonyme Funktion in Java schreiben?

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

Privacy policy