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
javatiene sub-paquetes awt, applet, io, lang, net, y utilunidades, pero no hay compilación.
- El paquete
java.awttiene 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.awttiene 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
mousey un tipo de miembro Buttonen ese paquete (que luego podría denominarse mouse.Button), entonces no puede haber ningún paquete con el nombre completo mouse.Buttono mouse.Button.Click.
- Si
com.nighthacks.java.jages el nombre completo de un tipo, entonces no puede haber ningún paquete cuyo nombre completo sea com.nighthacks.java.jago 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 olivery otro paquete llamado oliver.twist, o entre paquetes nombrados evelyn.woody evelyn.waugh. Es decir, el código en un paquete llamado oliver.twistno tiene mejor acceso a los tipos declarados dentro del paquete oliverque 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.projy 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/projy
src/test/java/odp/projrespectivamente. Cuando la herramienta de compilación compila esto, ambos conjuntos de archivos terminan en el odp.projpaquete, pero solo los srcarchivos 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.