Większość odpowiedzi stwierdzała, że w Javie nie ma czegoś takiego jak podpakiet, ale nie jest to do końca dokładne. Termin ten znajdował się w specyfikacji języka Java już w Javie 6 i prawdopodobnie później (nie wydaje się, aby istniała swobodnie dostępna wersja JLS dla wcześniejszych wersji Java). Język wokół podpakietów nie zmienił się zbytnio w JLS od czasu Java 6.
Składowymi pakietu są jego podpakiety oraz wszystkie typy klas najwyższego poziomu i typy interfejsów najwyższego poziomu zadeklarowane we wszystkich jednostkach kompilacji pakietu.
Na przykład w Java SE Platform API:
- Pakiet
javama podpakietów awt, applet, io, lang, net, i utiljednostki, ale nie kompilacji.
- Pakiet
java.awtma nazwany podpakiet image, a także kilka jednostek kompilacji zawierających deklaracje typów klas i interfejsów.
Koncepcja podpakietu jest istotna, ponieważ wymusza ograniczenia nazewnictwa między pakietami i klasami / interfejsami:
Pakiet nie może zawierać dwóch elementów członkowskich o tej samej nazwie lub może wystąpić błąd w czasie kompilacji.
Oto kilka przykładów:
- Ponieważ pakiet
java.awtzawiera podpakiet image, nie może (i nie zawiera) deklaracji klasy lub typu interfejsu o nazwie image.
- Jeśli w pakiecie znajduje się pakiet o nazwie
mousei typ elementu członkowskiego Button(który następnie może być określany jako mouse.Button), nie może istnieć żaden pakiet o w pełni kwalifikowanej nazwie mouse.Buttonlub mouse.Button.Click.
- Jeśli
com.nighthacks.java.jagjest w pełni kwalifikowaną nazwą typu, nie może istnieć żaden pakiet, którego w pełni kwalifikowaną nazwą jest albo com.nighthacks.java.jaglub com.nighthacks.java.jag.scrabble.
Jednak to ograniczenie nazewnictwa jest jedynym znaczeniem, jakie język nadaje podpakietom:
Hierarchiczna struktura nazewnictwa paczek ma być wygodna do organizowania powiązanych paczek w konwencjonalny sposób, ale sama w sobie nie ma żadnego znaczenia poza zakazem dotyczącym paczki mającej podpakiet o tej samej nazwie prostej, co typ najwyższego poziomu zadeklarowany w tym pakiecie .
Na przykład nie ma specjalnej relacji dostępu między pakietem o nazwie olivera innym pakietem o nazwie oliver.twistlub między pakietami o nazwie evelyn.woodi evelyn.waugh. Oznacza to, że kod w pakiecie o nazwie oliver.twistnie ma lepszego dostępu do typów zadeklarowanych w pakiecie oliverniż kod w jakimkolwiek innym pakiecie.
W tym kontekście możemy odpowiedzieć na samo pytanie. Ponieważ wyraźnie nie ma specjalnej relacji dostępu między pakietem a jego podpakietem lub między dwoma różnymi podpakietami pakietu nadrzędnego, w języku nie ma możliwości, aby metoda była widoczna dla dwóch różnych pakietów w żądany sposób. Jest to udokumentowana, celowa decyzja projektowa.
Albo metodę można upublicznić, a wszystkie pakiety (w tym odp.proji odp.proj.test) będą mogły uzyskać dostęp do podanych metod, albo metoda może zostać ustawiona jako prywatna (domyślna widoczność), a cały kod, który musi uzyskać bezpośredni dostęp, musi zostać umieszczony ten sam (pod) pakiet co metoda.
To powiedziawszy, bardzo standardową praktyką w Javie jest umieszczanie kodu testowego w tym samym pakiecie co kod źródłowy, ale w innym miejscu w systemie plików. Na przykład w narzędziu do kompilacji Maven konwencja będzie taka, aby umieścić te pliki źródłowe i testowe odpowiednio w src/main/java/odp/proji
src/test/java/odp/proj. Kiedy narzędzie kompilacji to kompiluje, oba zestawy plików trafiają do odp.projpakietu, ale tylko te srcpliki są uwzględniane w artefakcie produkcyjnym; pliki testowe są używane tylko w czasie kompilacji do weryfikacji plików produkcyjnych. Dzięki tej konfiguracji kod testowy może swobodnie uzyskiwać dostęp do dowolnego kodu prywatnego lub chronionego kodu testowanego kodu, ponieważ będą one znajdować się w tym samym pakiecie.
W przypadku, gdy chcesz udostępniać kod między podpakietami lub pakietami rodzeńskimi, które nie są przypadkiem testowym / produkcyjnym, jednym z rozwiązań, które widziałem w niektórych bibliotekach, jest umieszczenie tego udostępnionego kodu jako publicznego, ale udokumentuj, że jest on przeznaczony dla biblioteki wewnętrznej tylko do użytku.