La plupart des réponses ici ont déclaré qu'il n'existe pas de sous-paquetage en Java, mais ce n'est pas strictement exact. Ce terme a été dans la spécification du langage Java aussi loin que Java 6, et probablement plus loin (il ne semble pas y avoir de version librement accessible du JLS pour les versions antérieures de Java). Le langage autour des sous-packages n'a pas beaucoup changé dans le JLS depuis Java 6.
Les membres d'un package sont ses sous-packages et tous les types de classe de niveau supérieur et les types d'interface de niveau supérieur déclarés dans toutes les unités de compilation du package.
Par exemple, dans l'API Java SE Platform:
- Le paquet
java
a sous - paquets awt
, applet
, io
, lang
, net
et util
, mais aucune unité de compilation.
- Le paquet
java.awt
a un sous-paquet nommé image
, ainsi qu'un certain nombre d'unités de compilation contenant des déclarations de types de classe et d'interface.
Le concept de sous-package est pertinent, tout comme il applique des contraintes de dénomination entre les packages et les classes / interfaces:
Un package ne peut pas contenir deux membres du même nom, ou une erreur de compilation en résulte.
Voici quelques exemples:
- Étant donné que le package
java.awt
a un sous-package image
, il ne peut pas (et ne contient pas) de déclaration d'une classe ou d'un type d'interface nommé image
.
- S'il y a un package nommé
mouse
et un type de membre Button
dans ce package (qui pourrait alors être appelé mouse.Button
), il ne peut pas y avoir de package avec le nom complet mouse.Button
ou mouse.Button.Click
.
- Si
com.nighthacks.java.jag
est le nom complet d'un type, alors il ne peut y avoir aucun package dont le nom complet est soit com.nighthacks.java.jag
ou com.nighthacks.java.jag.scrabble
.
Cependant, cette restriction de dénomination est la seule signification accordée aux sous-packages par le langage:
La structure de dénomination hiérarchique pour les packages est destinée à être pratique pour organiser les packages liés de manière conventionnelle, mais n'a aucune signification en soi autre que l'interdiction pour un package d'avoir un sous-package avec le même nom simple qu'un type de niveau supérieur déclaré dans ce package .
Par exemple, il n'y a pas de relation d'accès spéciale entre un package nommé oliver
et un autre package nommé oliver.twist
, ou entre les packages nommés evelyn.wood
et evelyn.waugh
. Autrement dit, le code d'un package nommé oliver.twist
n'a pas de meilleur accès aux types déclarés dans le package oliver
que le code de tout autre package.
Dans ce contexte, nous pouvons répondre à la question elle-même. Puisqu'il n'y a explicitement aucune relation d'accès spéciale entre un package et son sous-package, ou entre deux sous-packages différents d'un package parent, il n'y a aucun moyen dans le langage de rendre une méthode visible à deux packages différents de la manière demandée. Il s'agit d'une décision de conception documentée et intentionnelle.
Soit la méthode peut être rendue publique et tous les packages (y compris odp.proj
et odp.proj.test
) pourront accéder aux méthodes données, soit la méthode peut être rendue package private (la visibilité par défaut), et tout le code qui doit y accéder directement doit le mettre le même (sous) package que la méthode.
Cela dit, une pratique très courante en Java consiste à placer le code de test dans le même package que le code source, mais à un emplacement différent sur le système de fichiers. Par exemple, dans l' outil de construction Maven , la convention serait de placer ces fichiers source et test dans src/main/java/odp/proj
et
src/test/java/odp/proj
, respectivement. Lorsque l'outil de construction compile cela, les deux ensembles de fichiers se retrouvent dans le odp.proj
package, mais seuls les src
fichiers sont inclus dans l'artefact de production; les fichiers de test ne sont utilisés qu'au moment de la construction pour vérifier les fichiers de production. Avec cette configuration, le code de test peut accéder librement à n'importe quel code privé ou protégé du code qu'il teste, car ils seront dans le même package.
Dans le cas où vous souhaitez un partage de code entre des sous-packages ou des packages frères qui ne sont pas le cas de test / production, une solution que j'ai vue dans certaines bibliothèques consiste à rendre ce code partagé public, mais à documenter qu'il est destiné à la bibliothèque interne utiliser seulement.