BT

Diffuser les Connaissances et l'Innovation dans le Développement Logiciel d'Entreprise

Contribuez

Sujets

Sélectionner votre région

Accueil InfoQ Actualités Java Nestmates fait des progrès

Java Nestmates fait des progrès

NDT : L'article original joue sur le double sens de nest en anglais. Il s'agit à la fois de classes imbriquées - nested classes et du nid - nest. Le terme nestmate fait référence lui aux membres d'un même nid. Plutôt qu'une traduction un peu artificielle, il semblait préférable de conserver le terme original.

Oracle a annoncé la JEP 181 - "Contrôle d'Accès basé sur Nest" - connu également sous le nom de "Nestmates". Ceci consiste en une amélioration technique de la plate-forme qui rembourse une dette architecturale de 20 ans introduite dans Java 1.1.

La nouvelle fonctionnalité est connectée à l'implémentation des classes imbriquées de Java (qui sont souvent appelées "classes internes", bien qu'il n'y ait qu'un seul type possible de classe imbriquée).

En général, les types imbriqués sont utilisés à deux fins distinctes, toutes deux liées à l'encapsulation. D'une part, un type peut être seulement requis pour une raison très spécifique, et dans une section de code très limitée. Cela signifie qu'il doit être étroitement localisé, car il fait partie des détails d'implémentation. Dans les anciennes versions de Java, la seule façon d'y parvenir était d'utiliser un type imbriqué, comme une implémentation anonyme d'une interface. En pratique, avec l'avènement de Java 8, ce cas d'utilisation a été largement repris dans les expressions lambda et l'utilisation de types anonymes en tant que types localisés a considérablement diminué, bien qu'elle persiste dans certains cas.

D'autre part, un type peut être imbriqué car il a besoin d'un accès privé aux fonctionnements internes d'un autre type. En tant que type imbriqué (c'est-à-dire en tant que membre), il a le même accès que les variables et méthodes membres. Cela signifie que les types imbriqués ont un accès privilégié et peuvent être considérés comme "une légère déformation des règles d'encapsulation".

Une autre manière de raisonner à propos de ce cas d'utilisation des types imbriqués est de considérer qu'ils sont liés d'une manière ou d'une autre à un autre type. Cela signifie qu'ils n'ont pas vraiment d'existence indépendante en tant qu'entité et ne vivent qu'en coexistence avec un autre type.

Le but du JEP Nestmates est de généraliser et de formaliser cette relation symbiotique entre les types et d'améliorer la mise en œuvre actuelle, qui comporte une certaine quantité de dette technique et passe plutôt pour un hack de nos jours.

Jusqu'à Java 10, les classes imbriquées sont compilées dans des fichiers de classes de niveau supérieur séparés, mais avec une convention de nommage spéciale, de sorte qu'une classe imbriquée Nested dans une classeOuter est compilée dans un fichier nommé Outer$Nested.class. Le problème avec cette stratégie d'implémentation est que selon les règles du langage Java, une classe imbriquée a accès à tous les membres de la classe englobante, y compris les membres privés.

Pour résoudre ce problème, javac ajoute des méthodes d'accès synthétiques supplémentaires àOuter pour autoriser l'accès. Par exemple, cette classe interne simple :

public class Outer {
    private int i = 0;

    public class Inner {
        public int i() {
            return i;
        }
    }
}

devient deux fichiers class, Outer.class and Outer$Inner.class avec le bytecode suivant :

public class Outer {
  private int i;

  public Outer();
    Code:
       0: aload_0
       1: invokespecial #2                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: iconst_0
       6: putfield      #1                  // Field i:I
       9: return

  static int access$000(Outer);
    Code:
       0: aload_0
       1: getfield      #1                  // Field i:I
       4: ireturn
}

et

public class Outer$Inner {
  final Outer this$0;

  public Outer$Inner(Outer);
    Code:
       0: aload_0
       1: aload_1
       2: putfield      #1                  // Field this$0:LOuter;
       5: aload_0
       6: invokespecial #2                  // Method java/lang/Object."<init>":()V
       9: return

  public int i();
    Code:
       0: aload_0
       1: getfield      #1                  // Field this$0:LOuter;
       4: invokestatic  #3                  // Method Outer.access$000:(LOuter;)I
       7: ireturn
}

L'accès privé requis par la classe interne a été transformé par le compilateur en une méthode d'accès de portée de paquetage access$000() sur Outer. L'existence de cet accesseur synthétique signifie que les développeurs qui connaissent le mécanisme peuvent y accéder, soit directement, soit par réflexion - même depuis une classe non-imbriquée de la classe d'origine.

Avec les mesures prises pour améliorer le contrôle d'accès dans le cadre de la feuille de route de Java, cet aspect des types imbriqués se distingue comme ayant besoin d'un nettoyage ou comme le PEC en décrit la motivation :

Une notion formelle d'un groupe de fichiers de classe formant un nid, où les nestmates partagent un mécanisme commun de contrôle d'accès, permet d'obtenir directement le résultat souhaité d'une manière plus simple, plus sûre et plus transparente.

La description du JEP note également que les améliorations futures pourraient inclure :

  • Dans la spécialisation générique, chaque type spécialisé peut être créé en tant que nestmate du type générique.
  • Un remplacement sûr et supporté de l'API Unsafe.defineAnonymousClass() pourrait créer la nouvelle classe en tant que nestmate d'une classe existante.
  • Le concept de "classes scellées" pourrait être effectué en autorisant seulement les sous-classes comme nestmate.
  • Des types imbriqués vraiment privés peuvent être réalisés (les types imbriqués privés sont actuellement définis avec l'accès de portée paquetage).

Les classes scellées et les types véritablement privés sont susceptibles d'être populaires auprès des développeurs travaillant dans Scala et dans d'autres langages, car ils fournissent les éléments de base nécessaires à la mise en œuvre d'idées telles que les types de données algébriques.

Nestmates est en cours de développement dans le cadre du Projet Valhalla et l'effort pour produire un prototype initial est en cours par les développeurs d'OpenJDK.

Comme d'habitude pour les fonctionnalités à long terme, Oracle n'a pris aucun engagement quant au moment où (le cas échéant) Nestmates sera livré. Toutefois, compte tenu de son utilité pour d'autres fonctionnalités phares (telles que les classes scellées et le pattern matching) actuellement en cours de développement, les programmeurs Java intéressés devraient garder un œil sur l'avancement du projet.

Evaluer cet article

Pertinence
Style

Contenu Éducatif

BT