La mayoría de las respuestas aquí han declarado que no hay tal cosa como un subpaquete en Java, pero eso no es estrictamente exacto. Este término ha estado en la especificación del lenguaje Java desde Java 6, y probablemente más atrás (no parece haber una versión de JLS de libre acceso para versiones anteriores de Java). El lenguaje alrededor de los subpaquetes no ha cambiado mucho en el JLS desde Java 6.
Los miembros de un paquete son sus subpaquetes y todos los tipos de clase de nivel superior y los tipos de interfaz de nivel superior declarados en todas las unidades de compilación del paquete.
Por ejemplo, en la API de la plataforma Java SE:
- El paquete
java
tiene sub-paquetes awt
, applet
, io
, lang
, net
, y util
unidades, pero no hay compilación.
- El paquete
java.awt
tiene un subpaquete denominado image
, así como varias unidades de compilación que contienen declaraciones de clase y tipos de interfaz.
El concepto de subpaquete es relevante, ya que impone restricciones de nomenclatura entre paquetes y clases / interfaces:
Un paquete no puede contener dos miembros con el mismo nombre o un resultado de error en tiempo de compilación.
Aquí hay unos ejemplos:
- Debido a que el paquete
java.awt
tiene un subpaquete image
, no puede (y no contiene) una declaración de una clase o tipo de interfaz llamado image
.
- Si hay un paquete con nombre
mouse
y un tipo de miembro Button
en ese paquete (que luego podría denominarse mouse.Button
), entonces no puede haber ningún paquete con el nombre completo mouse.Button
o mouse.Button.Click
.
- Si
com.nighthacks.java.jag
es el nombre completo de un tipo, entonces no puede haber ningún paquete cuyo nombre completo sea com.nighthacks.java.jag
o com.nighthacks.java.jag.scrabble
.
Sin embargo, esta restricción de nomenclatura es el único significado que el lenguaje otorga a los subpaquetes:
La estructura de nomenclatura jerárquica para paquetes está pensada para ser conveniente para organizar paquetes relacionados de una manera convencional, pero no tiene importancia en sí misma aparte de la prohibición de que un paquete tenga un subpaquete con el mismo nombre simple que un tipo de nivel superior declarado en ese paquete .
Por ejemplo, no hay una relación de acceso especial entre un paquete llamado oliver
y otro paquete llamado oliver.twist
, o entre paquetes nombrados evelyn.wood
y evelyn.waugh
. Es decir, el código en un paquete llamado oliver.twist
no tiene mejor acceso a los tipos declarados dentro del paquete oliver
que el código en cualquier otro paquete.
Con este contexto, podemos responder la pregunta en sí. Dado que no existe una relación de acceso especial entre un paquete y su subpaquete, o entre dos subpaquetes diferentes de un paquete padre, no hay forma dentro del lenguaje de hacer que un método sea visible para dos paquetes diferentes de la manera solicitada. Esta es una decisión de diseño intencional documentada.
O el método puede hacerse público y todos los paquetes (incluidos odp.proj
y odp.proj.test
) podrán acceder a los métodos dados, o el método podría hacerse privado (la visibilidad predeterminada), y todo el código que necesita acceder directamente a él debe incluirse el mismo (sub) paquete que el método.
Dicho esto, una práctica muy estándar en Java es colocar el código de prueba en el mismo paquete que el código fuente, pero en una ubicación diferente en el sistema de archivos. Por ejemplo, en la herramienta de compilación Maven , la convención sería colocar estos archivos fuente y de prueba en , src/main/java/odp/proj
y
src/test/java/odp/proj
respectivamente. Cuando la herramienta de compilación compila esto, ambos conjuntos de archivos terminan en el odp.proj
paquete, pero solo los src
archivos se incluyen en el artefacto de producción; los archivos de prueba solo se usan en el momento de la compilación para verificar los archivos de producción. Con esta configuración, el código de prueba puede acceder libremente a cualquier código privado o protegido del paquete del código que está probando, ya que estarán en el mismo paquete.
En el caso en que desee compartir código entre subpaquetes o paquetes hermanos que no sea el caso de prueba / producción, una solución que he visto que algunas bibliotecas usan es poner ese código compartido como público, pero documentar que está destinado a la biblioteca interna Usar unicamente.