Envoyé par
zhero
Question : pourquoi écris-tu
au lieu de
ou
?
Tu parles de cette instruction KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this::dispatchKeyEvent);C'est justement une spécificité Java 8. On appelle ça une réféfence de méthode.
La méthode addKeyEventDispatcher de la classe KeyboardFocusManager, type de retour de KeyboardFocusManager.getCurrentKeyboardFocusManager(), prend en paramètre un objet de type KeyEventDispatcher, qui est défini comme une interface dite fonctionnelle, c'est-à-dire une interface à une seule méthode non implémentée.
Voici le code source de l'interface. On y voit justement une annotation, @FunctionalInterface, qui garanti en quelque sorte, que cette interface n'évoluera pas de manière à avoir d'autres méthodes
à implémenter :
1 2 3 4 5 6 7 8
| package java.awt;
import java.awt.event.KeyEvent;
@FunctionalInterface
public interface KeyEventDispatcher {
boolean dispatchKeyEvent(KeyEvent event);
} |
Avant Java 8, il fallait faire une implémentation de cette interface pour pouvoir avoir un paramètre à passer à KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(). Donc soit faire une classe :
1 2 3 4 5
| public class MyKeyEventDispatcher implements KeyEventDispatcher {
public boolean dispatchKeyEvent(KeyEvent event) {
// ici le code à faire
}
} |
puis
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher( new MyKeyEventDispatcher() );
ou encore faire une classe anonyme :
1 2 3 4 5
| KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher( new KeyEventDispatcher () {
public boolean dispatchKeyEvent(KeyEvent event) {
// ici le code à faire
}
} ); |
Java 8 introduit la notion d'expressions lambda et la notion de référence de méthode. Ces deux formes d'expressions syntaxiques permettent une implémentation d'interface fonctionnelle avoir moins de chose à écrire (que l'implémentation par classe, anonyme ou pas).
Par expression lamda, on aurait :
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(e-> ici le code à exécuter);
le e représente le paramètre de l'unique méthode, la flêche (->) indique que c'est une expression lambda.
Dans mon exemple, j'ai fait une méthode (dispatchKeyEvent) pour traiter l'évenement (parce qu'il y plusieurs cas, et que je voulais éviter d'avoir une écriture qui finalement n'était que très ressemblante à l'implémentation de la classe anonyme, donc :
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(e->dispatchKeyEvent(e));
Dans certain cas, on peut simplifier l'écriture de l'expression lambda on utilisant une référence de méthode :
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(this::dispatchKeyEvent);
C'est le :: qui indique qu'il s'agit d'une référence de méthode. Cette expression est équivalente à la précédente (dans le contexte).
Quant aux deux autres expressions que tu proposes :
Envoyé par
zhero
this.DispatchKeyEvent() ou DispatchKeyEvent() ?
elles sont tout simplement syntaxiquement incorrectes dans le contexte. La méthode addKeyEventDispatcher() prend un KeyEventDispatcher en paramètre, un objet donc. Pas une méthode. Surtout qu'on ne peut pas passer de méthode en paramètre d'une méthode. Les expressions lambda et références de méthode permettent justement de contourner cette impossiblité, en faisant quelque chose qui du point de vue syntaxique est raccourci par rapport à l'implémentation anonyme qui serait le seul autre moyen de faire quelque chose qui ressemble à un passage de méthode en paramètre.
A noter, également, de faire attention à la casse : Java y est sensible, ce qui veut dire que DispatchKeyEvent et dispatchKeyEvent, ce n'est pas la même chose.
Envoyé par
zhero
je suis en train d'apprendre java en formation et on ne s'est pas arrêté sur les spécificité de Java8.
Et là où ca me trouble plus c'est qu'en php par exemple c'est ce qu'on utilise pour appeller des méthodes statiques.
Les méthodes statiques en Java s'appellent simplement en indiquant le nom de la classe et la méthode :
1 2 3 4
| public class Exemple {
public static void uneMethodeStatique() {
}
} |
L'appel :
Exemple.uneMethodeStatique();
En réalité, on pourrait écrire :
1 2
| Exemple unExemple = new Exemple();
unExemple.uneMethodeStatique(); |
On ne le fait simplement pas, par convention, pour éviter la confusion que ça peut engendrer (qu'on pourrait penser qu'il s'agit d'une méthode qui agit sur un contexte non statique de l'instance), et d'ailleurs ceci est signalé par une alerte dans les IDE, ou lors de la compilation.
Partager