Est-ce même possible?
Réponses:
si vous parlez d'une fonction anonyme et que vous utilisez une version de Java antérieure à Java 8, alors en un mot, non. ( En savoir plus sur les expressions lambda si vous utilisez Java 8+ )
Cependant, vous pouvez implémenter une interface avec une fonction comme celle-ci:
Comparator<String> c = new Comparator<String>() {
int compare(String s, String s2) { ... }
};
et vous pouvez l'utiliser avec des classes internes pour obtenir une fonction presque anonyme :)
Voici un exemple de classe interne anonyme.
System.out.println(new Object() {
@Override public String toString() {
return "Hello world!";
}
}); // prints "Hello world!"
Ce n'est pas très utile en l'état, mais cela montre comment créer une instance d'une classe interne anonyme extends Object
et @Override
sa toString()
méthode.
Les classes internes anonymes sont très pratiques lorsque vous avez besoin d'implémenter une interface
classe qui n'est peut-être pas hautement réutilisable (et ne vaut donc pas la peine d'être refactorisée en sa propre classe nommée). Un exemple instructif est l'utilisation d'une coutume java.util.Comparator<T>
pour le tri.
Voici un exemple de la façon dont vous pouvez trier un en String[]
fonction de 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]"
Notez l'astuce de comparaison par soustraction utilisée ici. Il faut dire que cette technique est en général cassée: elle n'est applicable que lorsque l'on peut garantir qu'elle ne débordera pas (c'est le cas des String
longueurs).
EventListener
(sous) implémentations dans l'application Swing moyenne.
Linked
barre latérale, donc je fais de mon mieux pour l'utiliser.
Avec l'introduction de l'expression lambda dans Java 8, vous pouvez désormais avoir des méthodes anonymes.
Disons que j'ai une classe Alpha
et que je veux filtrer les Alpha
s sur une condition spécifique. Pour ce faire, vous pouvez utiliser un fichier Predicate<Alpha>
. Il s'agit d'une interface fonctionnelle qui a une méthode test
qui accepte un Alpha
et retourne un boolean
.
En supposant que la méthode de filtrage a cette signature:
List<Alpha> filter(Predicate<Alpha> filterPredicate)
Avec l'ancienne solution de classe anonyme, vous auriez besoin de quelque chose comme:
filter(new Predicate<Alpha>() {
boolean test(Alpha alpha) {
return alpha.centauri > 1;
}
});
Avec les lambdas Java 8, vous pouvez faire:
filter(alpha -> alpha.centauri > 1);
Pour plus d'informations, consultez le didacticiel sur les expressions Lambda
Des classes internes anonymes implémentant ou étendant l'interface d'un type existant ont été faites dans d'autres réponses, bien qu'il soit intéressant de noter que plusieurs méthodes peuvent être implémentées (souvent avec des événements de style JavaBean, par exemple).
Une caractéristique peu reconnue est que bien que les classes internes anonymes n'aient pas de nom, elles ont un type. De nouvelles méthodes peuvent être ajoutées à l'interface. Ces méthodes ne peuvent être invoquées que dans des cas limités. Principalement directement sur l' new
expression elle-même et au sein de la classe (y compris les initialiseurs d'instance). Cela peut dérouter les débutants, mais cela peut être "intéressant" pour la récursivité.
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);
}
(J'ai initialement écrit ceci en utilisant node
plutôt que cur
dans la print
méthode. Dites NON à la capture "implicitement final
" des locaux? )
node
doit être déclaré final
ici.
cur
.
"Node" +
pour rendre une deuxième méthode nécessaire). / Je n'ai pas de nom. Peut-être pourrais-je créer une question de dénomination «sondage» (CW), et la faire rejeter dans l'oubli.
Oui si vous utilisez le dernier java qui est la version 8. Java8 permet de définir des fonctions anonymes, ce qui était impossible dans les versions précédentes.
Prenons l'exemple de la documentation java pour savoir comment déclarer des fonctions et des classes anonymes
L'exemple suivant, HelloWorldAnonymousClasses, utilise des classes anonymes dans les instructions d'initialisation des variables locales frenchGreeting et spanishGreeting, mais utilise une classe locale pour l'initialisation de la variable 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();
}
}
Syntaxe des classes anonymes
Considérez l'instanciation de l'objet 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'expression de classe anonyme comprend les éléments suivants:
new
opérateurLe nom d'une interface à implémenter ou d'une classe à étendre. Dans cet exemple, la classe anonyme implémente l'interface HelloWorld.
Parenthèses contenant les arguments d'un constructeur, tout comme une expression de création d'instance de classe normale. Remarque: Lorsque vous implémentez une interface, il n'y a pas de constructeur, vous utilisez donc une paire vide de parenthèses, comme dans cet exemple.
Un corps, qui est un corps de déclaration de classe. Plus précisément, dans le corps, les déclarations de méthode sont autorisées mais les instructions ne le sont pas.