È anche possibile?
Risposte:
se intendi una funzione anonima e stai utilizzando una versione di Java precedente a Java 8, in una parola, no. ( Leggi le espressioni lambda se usi Java 8+ )
Tuttavia, puoi implementare un'interfaccia con una funzione come questa:
Comparator<String> c = new Comparator<String>() {
int compare(String s, String s2) { ... }
};
e puoi usarlo con le classi interne per ottenere una funzione quasi anonima :)
Ecco un esempio di una classe interna anonima.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
Questo non è molto utile così com'è, ma mostra come creare un'istanza di una classe interna anonima extends Object
e il @Override
suo toString()
metodo.
Le classi interne anonime sono molto utili quando è necessario implementare una interface
classe che potrebbe non essere altamente riutilizzabile (e quindi non vale la pena refactoring alla propria classe denominata). Un esempio istruttivo sta usando un'usanzajava.util.Comparator<T>
per l'ordinamento.
Ecco un esempio di come puoi ordinare un String[]
basato su 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]"
Nota il trucco del confronto per sottrazione usato qui. Va detto che questa tecnica in generale è rotta: è applicabile solo quando si può garantire che non trabocchi (come nel caso delle String
lunghezze).
EventListener
(sotto) implementazioni nell'applicazione Swing media.
Linked
barra laterale, quindi sto facendo del mio meglio per utilizzarla.
Con l'introduzione dell'espressione lambda in Java 8 ora puoi avere metodi anonimi.
Diciamo che ho un corso Alpha
e voglio filtrare Alpha
i messaggi in base a una condizione specifica. Per fare questo puoi usare un file Predicate<Alpha>
. Questa è un'interfaccia funzionale che ha un metodo test
che accetta Alpha
e restituisce a boolean
.
Supponendo che il metodo di filtro abbia questa firma:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
Con la vecchia soluzione di classe anonima avresti bisogno di qualcosa del tipo:
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
Con le lambda Java 8 puoi fare:
filter(alpha -> alpha.centauri > 1);
Per informazioni più dettagliate, consulta il tutorial Lambda Expressions
Classi interne anonime che implementano o estendono l'interfaccia di un tipo esistente sono state eseguite in altre risposte, anche se vale la pena notare che possono essere implementati più metodi (spesso con eventi in stile JavaBean, per esempio).
Una caratteristica poco riconosciuta è che sebbene le classi interne anonime non abbiano un nome, hanno un tipo. Nuovi metodi possono essere aggiunti all'interfaccia. Questi metodi possono essere richiamati solo in casi limitati. Principalmente direttamente new
sull'espressione stessa e all'interno della classe (inclusi gli inizializzatori di istanze). Potrebbe confondere i principianti, ma può essere "interessante" per la ricorsione.
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);
}
(L'ho scritto originariamente utilizzando node
piuttosto che cur
nel print
metodo. Di ' NO per catturare "implicitamente final
" i locali? )
node
dovrebbe essere dichiarato final
qui.
cur
.
"Node" +
per rendere necessario un secondo metodo). / Non ho un nome. Forse potrei creare una domanda di denominazione "sondaggio" (CW) e farla cadere nell'oblio.
Sì, se stai usando l'ultima java che è la versione 8. Java8 rende possibile definire funzioni anonime che era impossibile nelle versioni precedenti.
Prendiamo esempio dai documenti java per sapere come dichiarare funzioni, classi anonime
L'esempio seguente, HelloWorldAnonymousClasses, utilizza classi anonime nelle istruzioni di inizializzazione delle variabili locali frenchGreeting e spanishGreeting, ma utilizza una classe locale per l'inizializzazione della variabile 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();
}
}
Sintassi delle classi anonime
Considera l'istanza dell'oggetto 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);
}
};
L'espressione di classe anonima è composta da quanto segue:
new
operatoreIl nome di un'interfaccia da implementare o di una classe da estendere. In questo esempio, la classe anonima implementa l'interfaccia HelloWorld.
Parentesi che contengono gli argomenti di un costruttore, proprio come una normale espressione di creazione di istanze di classe. Nota: quando si implementa un'interfaccia, non è presente alcun costruttore, quindi si utilizza una coppia di parentesi vuota, come in questo esempio.
Un corpo, che è un corpo di dichiarazione di classe. Più specificamente, nel corpo, le dichiarazioni di metodo sono consentite ma le istruzioni no.