Maison Java javaDidacticiel Introduction détaillée à la méthode par défaut de Java8

Introduction détaillée à la méthode par défaut de Java8

Jan 23, 2017 pm 03:15 PM

Quelle est la méthode par défaut ?

Après la sortie de Java 8, de nouvelles méthodes peuvent être ajoutées à l'interface, mais l'interface peut toujours rester compatible avec sa classe d'implémentation. Ceci est important car la bibliothèque que vous développez peut être largement utilisée par plusieurs développeurs. Avant Java 8, après la publication d'une interface dans une bibliothèque de classes, si une nouvelle méthode était ajoutée à l'interface, les applications qui implémentaient cette interface risquaient de planter en utilisant la nouvelle version de l'interface.

Avec Java 8, n'y a-t-il pas un tel danger ? La réponse est non.

L'ajout de méthodes par défaut aux interfaces peut rendre certaines classes d'implémentation indisponibles.

Tout d’abord, regardons les détails de la méthode par défaut.

Dans Java 8, les méthodes dans les interfaces peuvent être implémentées (les méthodes statiques dans Java 8 peuvent également être implémentées dans les interfaces, mais c'est un autre sujet). La méthode implémentée dans l'interface est appelée méthode par défaut, qui est identifiée par le mot-clé default comme modificateur. Lorsqu'une classe implémente une interface, elle peut implémenter des méthodes déjà implémentées dans l'interface, mais ce n'est pas obligatoire. Cette classe héritera de la méthode par défaut. C'est pourquoi lorsque l'interface change, la classe d'implémentation n'a pas besoin d'être modifiée.

Qu’en est-il de l’héritage multiple ?

Lorsqu'une classe implémente plus d'une (par exemple deux) interfaces et que ces interfaces ont la même méthode par défaut, les choses deviennent très compliquées. De quelle méthode par défaut la classe hérite-t-elle ? Ni l'un ni l'autre! Dans ce cas, la classe elle-même (directement ou une classe supérieure dans l'arbre d'héritage) doit implémenter la méthode par défaut.

La même chose est vraie lorsqu'une interface implémente la méthode par défaut et qu'une autre interface déclare la méthode par défaut comme abstraite. Java 8 essaie d'éviter toute ambiguïté et de maintenir la rigueur. Si une méthode est déclarée dans plusieurs interfaces, aucune des implémentations par défaut ne sera héritée et vous obtiendrez une erreur de compilation.

Cependant, si vous avez compilé votre classe, il n'y aura aucune erreur de compilation. À ce stade, Java 8 est incohérent. Cela a ses propres raisons, et il y a plusieurs raisons. Je ne veux pas l'expliquer en détail ou en discuter en profondeur ici (car : la version est sortie, le temps de discussion est trop long, et cette plateforme n'a jamais eu une telle discussion).

1. Supposons que vous ayez deux interfaces et une classe d'implémentation.
2. L'une des interfaces implémente une méthode par défaut m().
3. Compilez ensemble l'interface et la classe d'implémentation.
4. Modifiez l'interface qui ne contient pas la méthode m() et déclarez la méthode m() comme abstraite.
5. Recompilez l'interface modifiée séparément.
6. Exécutez la classe d’implémentation.

Introduction détaillée à la méthode par défaut de Java8

La classe peut se dérouler normalement dans la situation ci-dessus. Cependant, vous ne pouvez pas recompiler avec l'interface modifiée, mais la compilation avec l'ancienne interface peut toujours s'exécuter. Suivant


1. Modifiez l'interface contenant la méthode abstraite m() et créez une implémentation par défaut.
2. Compilez l'interface modifiée
3. Exécutez la classe : échec.
Lorsque deux interfaces fournissent une implémentation par défaut pour la même méthode, cette méthode ne peut pas être appelée à moins que la classe d'implémentation n'implémente également la méthode par défaut (soit directement, soit plus haut dans la classe de l'arbre d'héritage effectue l'implémentation).

Introduction détaillée à la méthode par défaut de Java8

Cependant, cette classe est compatible. Il peut être chargé à l'aide de la nouvelle interface et peut même être exécuté, à condition qu'il n'appelle pas de méthodes ayant des implémentations par défaut dans les deux interfaces.


Exemple de code :

Introduction détaillée à la méthode par défaut de Java8

Pour illustrer l'exemple ci-dessus, j'ai créé un répertoire de test pour C.java, là se trouvent également 3 sous-répertoires en dessous, utilisés pour stocker I1.java et I2.java. Le répertoire test contient le code source C.java de classe C. Le répertoire de base contient la version de l'interface qui peut être compilée et exécutée. I1 contient la méthode m() avec une implémentation par défaut et I2 ne contient aucune méthode.

La classe d'implémentation contient la méthode main afin que nous puissions l'exécuter dans le test. Il vérifiera s'il existe des paramètres de ligne de commande, afin que nous puissions facilement effectuer des tests appelant m() et n'appelant pas m().

~/github/test$ cat C.java
public class C implements I1, I2 {
  public static void main(String[] args) {
    C c = new C();
    if(args.length == 0 ){
        c.m();
    }
  }
}
~/github/test$ cat base/I1.java
public interface I1 {
  default void m(){
    System.out.println("hello interface 1");
  }
}
~/github/test$ cat base/I2.java
public interface I2 {
}
Copier après la connexion

Utilisez la ligne de commande suivante pour compiler et exécuter :

~/github/test$ javac -cp .:base C.java
~/github/test$ java -cp .:base C
hello interface 1
Copier après la connexion

Le répertoire compatible contient l'interface I2 avec la méthode abstraite m() et l'interface I1 non modifiée.

~/github/test$ cat compatible/I2.java
public interface I2 {
  void m();
}
Copier après la connexion

Ceci ne peut pas être utilisé pour compiler la classe C :

~/github/test$ javac -cp .:compatible C.java
C.java:1: error: C is not abstract and does not override abstract method m() in I2
public class C implements I1, I2 {
   ^
1 error
Copier après la connexion

Le message d'erreur est très précis. Parce que nous avons la C.class obtenue dans la compilation précédente, si nous compilons les interfaces dans le répertoire compatible, nous obtiendrons toujours deux interfaces pouvant exécuter la classe d'implémentation :

~/github/test$ javac compatible/I*.java
~/github/test$ java -cp .:compatible C
hello interface 1
Copier après la connexion

Le troisième répertoire est appelé faux, l'interface I2 incluse définit également la méthode m() :

~/github/test$ cat wrong/I2.java
public interface I2 {
  default void m(){
    System.out.println("hello interface 2");
  }
}
Copier après la connexion

我们应该不厌其烦的编译它。尽管m()方法被定义了两次,但是,实现类仍然可以运行,只要它没有调用那个定义了多次的方法,但是,只要我们调用m()方法,立即就会失败。这是我们使用的命令行参数:

~/github/test$ javac wrong/*.java
~/github/test$ java -cp .:wrong C
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting
default methods: I1.m I2.m
    at C.m(C.java)
    at C.main(C.java:5)
~/github/test$ java -cp .:wrong C x
~/github/test$
Copier après la connexion

结论

当你把给接口添加了default实现的类库移植到Java 8环境下的时候,一般不会有问题。至少Java8类库开发者给集合类添加default方法的时候就是这么想的。使用你类库的应用程序仍然依赖没有default方法的Java7的类库。当使用和修改多个不同的类库的时候,有很小的几率会发生冲突。如何才能避免呢?

像以前那样设计你的类库。可能依赖default方法的时候不要掉以轻心。万不得已不要使用。明智的选择方法名,避免和其它接口产生冲突。我们将会学习到Java编程中如何使用这个特性做开发。

更多Introduction détaillée à la méthode par défaut de Java8相关文章请关注PHP中文网!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Comment fonctionne le mécanisme de chargement de classe de Java, y compris différents chargeurs de classe et leurs modèles de délégation? Mar 17, 2025 pm 05:35 PM

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Comment implémenter la mise en cache à plusieurs niveaux dans les applications Java à l'aide de bibliothèques comme la caféine ou le cache de goyave? Mar 17, 2025 pm 05:44 PM

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Comment puis-je utiliser JPA (Java Persistance API) pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux? Mar 17, 2025 pm 05:43 PM

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Comment utiliser Maven ou Gradle pour la gestion avancée de projet Java, la création d'automatisation et la résolution de dépendance? Mar 17, 2025 pm 05:46 PM

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.

Mar 17, 2025 pm 05:45 PM

L'article discute de la création et de l'utilisation de bibliothèques Java personnalisées (fichiers JAR) avec un versioning approprié et une gestion des dépendances, à l'aide d'outils comme Maven et Gradle.

See all articles