J'ai deux packages dans mon projet: odp.proj
et odp.proj.test
. Il y a certaines méthodes que je souhaite voir uniquement pour les classes de ces deux packages. Comment puis-je faire ceci?
EDIT: S'il n'y a pas de concept de sous-paquet en Java, y a-t-il un moyen de contourner cela? J'ai certaines méthodes que je veux être disponibles uniquement pour les testeurs et les autres membres de ce package. Dois-je tout jeter dans le même paquet? Utilisez une réflexion approfondie?
java
package
visibility
encapsulation
Nick Heiner
la source
la source
Réponses:
Vous ne pouvez pas. En Java, il n'y a pas de concept de sous-package, donc
odp.proj
etodp.proj.test
sont des packages complètement séparés.la source
Les noms de vos packages indiquent que l'application ici est destinée aux tests unitaires. Le modèle typique utilisé est de mettre les classes que vous souhaitez tester et le code de test unitaire dans le même package (dans votre cas
odp.proj
) mais dans des arborescences sources différentes. Ainsi, vous mettriez vos classessrc/odp/proj
et votre code de testtest/odp/proj
.Java a le modificateur d'accès "package" qui est le modificateur d'accès par défaut quand aucun n'est spécifié (c'est-à-dire que vous ne spécifiez pas public, privé ou protégé). Avec le modificateur d'accès "package", seules les classes de
odp.proj
auront accès aux méthodes. Mais gardez à l'esprit qu'en Java, les modificateurs d'accès ne peuvent pas être utilisés pour appliquer les règles d'accès car avec la réflexion, tout accès est possible. Les modificateurs d'accès sont simplement suggestifs (sauf si un gestionnaire de sécurité restrictif est présent).la source
Il n'y a pas de relation spéciale entre
odp.proj
etodp.proj.test
- ils sont simplement nommés comme apparemment liés.Si le package odp.proj.test fournit simplement des tests, vous pouvez utiliser le même nom de package (
odp.proj
). Les IDE comme Eclipse et Netbeans créeront des dossiers séparés (src/main/java/odp/proj
etsrc/test/java/odp/proj
) avec le même nom de package mais avec la sémantique JUnit.Notez que ces IDE généreront des tests pour les méthodes dans
odp.proj
et créeront le dossier approprié pour les méthodes de test dans lesquelles il n'existe pas.la source
Quand je fais cela dans IntelliJ, mon arbre source ressemble à ceci:
la source
Cela dépend probablement un peu de vos motivations pour ne pas les afficher, mais si la seule raison est que vous ne voulez pas polluer l'interface publique avec des choses destinées uniquement à des tests (ou une autre chose interne), je mettrais les méthodes dans un une interface publique distincte et que les consommateurs des méthodes «cachées» utilisent cette interface. Cela n'empêchera pas les autres d'utiliser l'interface, mais je ne vois aucune raison pour laquelle vous devriez le faire.
Pour les tests unitaires, et s'il est possible sans réécrire le lot, suivez les suggestions pour utiliser le même package.
la source
Comme d'autres l'ont expliqué, il n'existe pas de "sous-paquetage" en Java: tous les paquets sont isolés et n'héritent en rien de leurs parents.
Un moyen simple d'accéder aux membres de classe protégés à partir d'un autre package consiste à étendre la classe et à remplacer les membres.
Par exemple, pour accéder
ClassInA
au packagea.b
:créez une classe dans ce package qui remplace les méthodes dont vous avez besoin dans
ClassInA
:Cela vous permet d'utiliser la classe de substitution à la place de la classe dans l'autre package:
Notez que cela ne fonctionne que pour les membres protégés, qui sont visibles pour les classes étendues (héritage), et non pour les membres privés de package qui ne sont visibles que pour les sous-classes / extensions dans le même package. Espérons que cela aide quelqu'un!
la source
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.
Java 13 JLS :
Le concept de sous-package est pertinent, tout comme il applique des contraintes de dénomination entre les packages et les classes / interfaces:
Cependant, cette restriction de dénomination est la seule signification accordée aux sous-packages par le langage:
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
etodp.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
etsrc/test/java/odp/proj
, respectivement. Lorsque l'outil de construction compile cela, les deux ensembles de fichiers se retrouvent dans leodp.proj
package, mais seuls lessrc
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.
la source
Sans mettre le modificateur d'accès devant la méthode, vous dites qu'il s'agit d'un package privé.
Regardez l'exemple suivant.
la source
Avec la classe PackageVisibleHelper, et gardez-la privée avant PackageVisibleHelperFactory gelé, nous pouvons appeler la méthode launchA (par PackageVisibleHelper) n'importe où :)
la source