La maggior parte delle risposte qui ha affermato che non esiste un pacchetto secondario in Java, ma ciò non è strettamente accurato. Questo termine è stato nelle specifiche del linguaggio Java fin da Java 6, e probabilmente anche più indietro (non sembra esserci una versione liberamente accessibile di JLS per le versioni precedenti di Java). La lingua attorno ai pacchetti secondari non è cambiata molto in JLS da Java 6.
I membri di un pacchetto sono i suoi pacchetti secondari e tutti i tipi di classe di livello superiore e i tipi di interfaccia di livello superiore dichiarati in tutte le unità di compilazione del pacchetto.
Ad esempio, nell'API della piattaforma Java SE:
- Il pacchetto
java
ha sottopackage awt
, applet
, io
, lang
, net
, e util
le unità, ma non di compilazione.
- Il pacchetto
java.awt
ha un pacchetto secondario denominato image
, oltre a un numero di unità di compilazione contenenti dichiarazioni di classe e tipi di interfaccia.
Il concetto di subpackage è rilevante, così come impone vincoli di denominazione tra pacchetti e classi / interfacce:
Un pacchetto non può contenere due membri con lo stesso nome o un errore di compilazione risulta.
Ecco alcuni esempi:
- Poiché il pacchetto
java.awt
ha un pacchetto secondario image
, non può (e non contiene) una dichiarazione di una classe o di un tipo di interfaccia denominato image
.
- Se esiste un pacchetto denominato
mouse
e un tipo di membro Button
in quel pacchetto (che quindi potrebbe essere indicato come mouse.Button
), allora non può esserci alcun pacchetto con il nome completo mouse.Button
o mouse.Button.Click
.
- Se
com.nighthacks.java.jag
è il nome completo di un tipo, non può esserci alcun pacchetto il cui nome completo sia com.nighthacks.java.jag
o com.nighthacks.java.jag.scrabble
.
Tuttavia, questa restrizione di denominazione è l' unico significato dato ai pacchetti secondari dalla lingua:
La struttura gerarchica di denominazione per i pacchetti è utile per organizzare i pacchetti correlati in modo convenzionale, ma non ha alcun significato in sé oltre al divieto di un pacchetto con un pacchetto secondario con lo stesso nome semplice di un tipo di livello superiore dichiarato in quel pacchetto .
Ad esempio, non esiste una relazione di accesso speciale tra un pacchetto denominato oliver
e un altro pacchetto denominato oliver.twist
o tra pacchetti denominati evelyn.wood
e evelyn.waugh
. Cioè, il codice in un pacchetto denominato oliver.twist
non ha un migliore accesso ai tipi dichiarati all'interno del pacchetto oliver
rispetto al codice in qualsiasi altro pacchetto.
Con questo contesto, possiamo rispondere alla domanda stessa. Poiché non esiste esplicitamente una relazione di accesso speciale tra un pacchetto e il suo pacchetto secondario o tra due pacchetti secondari diversi di un pacchetto padre, non esiste alcun modo all'interno della lingua per rendere visibile un metodo a due pacchetti diversi nel modo richiesto. Questa è una decisione di progettazione documentata e intenzionale.
Il metodo può essere reso pubblico e tutti i pacchetti (inclusi odp.proj
e odp.proj.test
) saranno in grado di accedere ai metodi indicati, oppure il metodo potrebbe essere reso pacchetto privato (la visibilità predefinita) e deve essere inserito tutto il codice che deve accedervi direttamente lo stesso (sotto) pacchetto del metodo.
Detto questo, una pratica molto standard in Java è quella di inserire il codice di test nello stesso pacchetto del codice sorgente, ma in una posizione diversa sul file system. Ad esempio, nello strumento di compilazione Maven , la convenzione sarebbe quella di inserire questi file di origine e di test in src/main/java/odp/proj
e
src/test/java/odp/proj
, rispettivamente. Quando lo strumento di compilazione lo compila, entrambi i set di file finiscono nel odp.proj
pacchetto, ma solo i src
file sono inclusi nell'artefatto di produzione; i file di test vengono utilizzati solo al momento della creazione per verificare i file di produzione. Con questa configurazione, il codice di test può accedere liberamente a qualsiasi pacchetto di codice privato o protetto del codice che sta testando, poiché si troveranno nello stesso pacchetto.
Nel caso in cui si desideri condividere il codice tra subpackage o pacchetti fratelli che non sono il caso di test / produzione, una soluzione che ho visto usare alcune librerie è quella di mettere quel codice condiviso come pubblico, ma documentare che è destinato alla libreria interna utilizzare solo.