Antworten:
Wenn Sie eine anonyme Funktion meinen und eine Version von Java vor Java 8 verwenden, dann in 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 der folgenden 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 :)
Hier ist ein Beispiel einer anonymen inneren Klasse.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
Dies ist zwar nicht sehr nützlich, zeigt jedoch, wie eine Instanz einer anonymen inneren Klasse extends Object
und @Override
deren toString()
Methode erstellt wird.
Anonyme innere Klassen sind sehr praktisch, wenn Sie eine implementieren müssen, interface
die möglicherweise nicht in hohem Maße wiederverwendbar ist (und daher keine Umgestaltung in eine eigene benannte Klasse wert ist). Ein lehrreiches Beispiel ist die Verwendung eines benutzerdefinierten java.util.Comparator<T>
Sortiers.
Hier ist ein Beispiel, wie Sie eine String[]
basierend auf sortieren können 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 Trick zum Vergleichen durch Subtraktion. Es sollte gesagt werden, dass diese Technik im Allgemeinen nicht funktioniert: Sie ist nur anwendbar, wenn Sie garantieren können, dass sie nicht überläuft (dies ist bei String
Längen der Fall ).
EventListener
(Unter-) Implementierungen in der durchschnittlichen Swing-Anwendung gefunden werden.
Linked
Seitenleiste hinzugefügt , daher gebe ich mein Bestes, um sie zu nutzen.
Mit der Einführung des Lambda-Ausdrucks in Java 8 können Sie jetzt anonyme Methoden verwenden.
Angenommen, ich habe eine Klasse Alpha
und möchte Alpha
s nach einer bestimmten Bedingung filtern . Dazu können Sie a verwenden Predicate<Alpha>
. Dies ist eine funktionale Schnittstelle mit einer Methode test
, die a akzeptiert Alpha
und a zurückgibtboolean
.
Angenommen, die Filtermethode hat diese Signatur:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
Mit der alten anonymen Klassenlösung 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);
Weitere Informationen finden Sie im Lambda Expressions-Tutorial
Anonyme innere Klassen, die die Schnittstelle eines vorhandenen Typs implementieren oder erweitern, wurden in anderen Antworten verwendet, obwohl es erwähnenswert ist, dass mehrere Methoden implementiert werden können (häufig häufig bei Ereignissen im JavaBean-Stil).
Ein wenig erkanntes Merkmal ist, dass anonyme innere Klassen zwar keinen Namen haben, aber einen Typ. Der Schnittstelle können neue Methoden hinzugefügt werden. Diese Methoden können nur in begrenzten Fällen aufgerufen werden. Hauptsächlich direkt auf den new
Ausdruck selbst und innerhalb der Klasse (einschließlich Instanzinitialisierer). Es mag 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 node
eher mit als cur
mit der print
Methode geschrieben. Sag NEIN zum Erfassen von "implizit final
" Einheimischen? )
node
sollte hier deklariert final
werden.
cur
.
"Node" +
, eine zweite Methode erforderlich zu machen). / Ich habe keinen Namen. Vielleicht könnte ich eine Frage mit dem Namen "Umfrage" (CW) erstellen und sie in Vergessenheit geraten lassen.
Ja, wenn Sie das neueste Java der Version 8 verwenden. Mit Java8 können anonyme Funktionen definiert werden, die in früheren Versionen nicht möglich waren.
Nehmen wir ein Beispiel aus Java-Dokumenten , 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, verwendet jedoch 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 frenchGreeting-Objekts:
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 folgenden Elementen:
new
BetreiberDer 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 zur Erstellung von Klasseninstanzen. Hinweis: Wenn Sie eine Schnittstelle implementieren, gibt es keinen Konstruktor. Daher verwenden Sie wie in diesem Beispiel ein leeres Klammerpaar.
Ein Body, der ein Klassendeklarationskörper ist. Insbesondere sind im Hauptteil Methodendeklarationen zulässig, Anweisungen jedoch nicht.