Ist es überhaupt möglich?
Wie kann ich eine anonyme Funktion in Java schreiben?
Aaron
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
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 Alpha
s 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
-
Methodenreferenzen sind ebenfalls nützlich. zB sort(String::compareToIgnoreCase) docs.oracle.com/javase/tutorial/java/javaOO/…
– Josiah Yoder
13. Januar 2015 um 21:10 Uhr
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?)
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.
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");
}
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