octobre
2007
Il y a énormément de discussion autour des (possibles) évolutions du langage dans Java 7, mais malheureusement elles sont majoritairement anglophone. Je vais donc tenter de présenter brièvement ces propositions d’évolution, en commençant par les Superpackages.
Les superpackages viennent combler certaines faiblesses des règles de visibilités de Java. En effet, mis à par pour les classes internes, les types Java ne peuvent avoir que deux types de visibilités :
Soit elles sont package-only, et uniquement visible par les classes du même package, soit elles sont public, et donc visible par « tout le monde ».
Mais public est « un peu trop publique »…
Problème
L’organisation des classes en packages et sous-packages est fortement limitée par cette règle de visibilité un peu trop simpliste, puisqu’on se retrouve obligé de déclarer une classe public à partir du moment où l’on souhaite l’utiliser depuis un autre package. Et de ce fait il est impossible d’utiliser une arborescence de package sans exposer certaines classes qui ne devrait pas l’être.
Prenons un exemple tout simple d’une librairie utilisant deux packages com.site.pack
et com.site.pack.impl
, dont le second contient des classes qui ne devraient pas être visible depuis les autres packages, mais qui doivent être utilisées par com.site.pack
.
Actuellement c’est tout à fait impossible, et la seule solution consiste à regrouper les deux packages en un seul et unique afin de pouvoir utiliser la visibilité package-only. Pas très pratique…
Les Superpackages
Les Superpackages rendront cela possible simplement en permettant de regrouper des packages et de définir classe par classe celles qui seront exportées ou pas (c’est à dire celle qui seront accessible depuis les autres packages, indépendamment de leurs visibilités).
Pour cela il faudra définir un superpackage en utilisant un fichier spécial nommé « super-package.java » :
// Déclaration du superpackage :
superpackage com.site.pack {
// Liste des packages qui appartiennent à ce superpackge :
member package com.site.pack, com.site.pack.impl;
// Liste des types exportés (visible en dehors du package) :
export com.site.pack.*;
}
Explication
On déclare un superpackage qui englobe les deux packages com.site.pack
et com.site.pack.impl
, mais qui n’exporte que les classes du package com.site.pack
. Ces dernières restent donc parfaitement visibles des autres packages en respectant les règles de visibilitées actuelles de Java. Par contre les classes du packages com.site.pack.impl
ne sont pas exportées, et elles sont alors totalement invisibles des autres packages même si elles sont déclarées public.
Ainsi le package com.site.pack
peut utiliser les classes publiques du package com.site.pack.impl
sans que ces dernières ne soient visibles depuis les autres packages. Tout cela sera bien entendu vérifié à la fois à la compilation et à l’exécution.
A noter qu’on peut également exporter les classes une à une (et donc cacher une seule classe d’un package par exemple), ou encore utiliser un superpackage comme membre d’un autre superpackage. Enfin l’API de réflection se verra ajouter une classe Superpackage
permettant de les manipuler au runtime.
Enfin, les Superpackages étant déjà défini par une JSR, il est fort probable qu’ils se retrouvent dans Java SE 7.
Avis
Clairement, les Superpackages ne vont pas révolutionner la vie des développeurs Java, mais ils seront incontestablement un plus non négligeable lors de la conception d’une librairie en permettant une meilleur modularité.
Pour allez plus loin…
- La JSR 294
- La proposition d’implémentation d’Andreas Sterbenz et Alex Buckley.
12 Commentaires + Ajouter un commentaire
Tutoriels
Discussions
- L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?
- Recuperation du nom des parametres
- Possibilité d'accéder au type générique en runtime
- [REFLEXION] Connaitre toutes les classes qui implémentent une interface
- jre 1.5, tomcat 6.0 et multi processeurs
- Classes, méthodes private
- Difference de performances Unix/Windows d'un programme?
- Définition exacte de @Override
- [ fuite ] memoire
Désolé mais ça ne sert à rien, comment la visibilité package qui elle aussi ne sert à rien et ne devrait pas exister (ça devrait être public par défaut).
Si ce genre de truc est validé, ça ne fera que complexifier l’apprentissage de Java inutilement.
Comment font les développeurs Python pour avoir tous leurs attributs et méthodes en public ? :
« we’re all consenting adults » (nous sommes entre adultes consentants)
Une fois au boulot, j’ai vu une classe où tout les attributs et méthodes étaient déclarés public… Bah oui au fond le programme compile.
Donc c’est avant tout au développeur que revient la responsabilité d’encapsuler.
Et ce n’est pas tout car les superpackages pourront être englobés dans une notion de module permettant entre autre la gestion des dépendances et des versions, le tout via la JSR 277…
a++
Merci adiGuba,
On peut rapprocher cette fonctionnalité avec ce qui est proposé pour développer un plugin Eclipse.
Il est ainsi possible d’exprimer quelles sont les API publics et celles qui sont privates. Je trouve ce principe très important. En effet, un client d’une API n’a pas besoin de voir la partie interne.
Malheureusement, actuellement en Java ce n’est pas possible. Alors je vote oui pour les superpackages.
La suite (pour de vrai car ce forum ne supporte pas les caractères inférieur et supérieur)…
Par exemple, actuellement, on a :
private void traiter() = visibilité réduite à la classe
public void traiter() = visibilité publique
void traiter() = visiblité package
Cette dernière syntaxe ne me plait pas dans la mesure où elle est induite et pas qualifié par un mot clé.
J’espère donc que l’introduction des superpackages corrigeront ce que me semble être une faiblesse du langage.
La suite…
Par exemple, actuellement, on a :
private void traiter()
+1 pour cette évolution.
Elle sera très intéressante pour les larges projet et le ficelage des API.
D’autre part, cela risque d’amener des modification sur les modifiers sur les méthodes. Par exemple, actuellement, on a :
private void traiter()
zedros >> il me semble qu’il existe un niveau de visibilité « internal » qui n’est visible que par les classes du même assembly, ce qui revient au même…
Sinon pour info Java devrait lui aussi se doter d’une gestion plus fine des modules via la JSR 277 (Java Module System).
a++
En C#, la notion d’assembly est à mon sens différente. En effet, le but principal est de gérer les dépendances entre modules. Par un exemple tel module en version ZZ dépend de tel module en version ZY et supérieure.
Je n’ai pas souvenir qu’il définisse de niveau de visibilité au sein de l’assembly.
My two cents
Ce n’est clairement pas utile pour un débutant, mais il n’y a aucune obligation de créer un superpackage
C’est un superbe fonctionnalité mais ça risque de compliquer encore les choses pour des débutants.
Il me semble que cela existe via la notion d’assembly… mais je ne saurais pas t’en dire plus !
a++
oui, ça me semble une bonne amélioration du langage.
Et j’aimerais bien savoir ce qu’il en ai des autres langages (C# notamment)