Ich habe zwei Pakete in meinem Projekt: odp.proj
und odp.proj.test
. Es gibt bestimmte Methoden, die nur für die Klassen in diesen beiden Paketen sichtbar sein sollen. Wie kann ich das machen?
EDIT: Wenn es in Java kein Konzept für ein Unterpaket gibt, gibt es einen Weg, dies zu umgehen? Ich habe bestimmte Methoden, die ich nur Testern und anderen Mitgliedern dieses Pakets zur Verfügung stellen möchte. Soll ich einfach alles in das gleiche Paket werfen? Verwenden Sie umfangreiche Reflexion?
java
package
visibility
encapsulation
Nick Heiner
quelle
quelle
Antworten:
Das kannst du nicht. In Java gibt es kein Konzept eines subpackage, so
odp.proj
undodp.proj.test
sind völlig getrennte Pakete.quelle
Die Namen Ihrer Pakete deuten darauf hin, dass die Anwendung hier für Unit-Tests vorgesehen ist. Das typische Muster besteht darin, die zu testenden Klassen und den Unit-Test-Code in demselben Paket (in Ihrem Fall
odp.proj
), jedoch in unterschiedlichen Quellbäumen abzulegen . Sie würden also Ihre Klassensrc/odp/proj
und Ihren Testcode eingebentest/odp/proj
.Java verfügt über den Zugriffsmodifikator "package", der der Standardzugriffsmodifikator ist, wenn keiner angegeben ist (dh Sie geben weder public, private noch protected an). Mit dem Zugriffsmodifikator "package" haben nur Klassen in
odp.proj
Zugriff auf die Methoden. Beachten Sie jedoch, dass in Java nicht auf die Zugriffsmodifikatoren zurückgegriffen werden kann, um Zugriffsregeln durchzusetzen, da mit Reflexion jeder Zugriff möglich ist. Zugriffsmodifikatoren sind lediglich ein Hinweis (es sei denn, ein restriktiver Sicherheitsmanager ist vorhanden).quelle
Dies ist keine besondere Beziehung zwischen
odp.proj
undodp.proj.test
- sie werden einfach als scheinbar verwandt bezeichnet.Wenn das Paket odp.proj.test lediglich Tests bereitstellt, können Sie denselben Paketnamen (
odp.proj
) verwenden. IDEs wie Eclipse und Netbeans erstellen separate Ordner (src/main/java/odp/proj
undsrc/test/java/odp/proj
) mit demselben Paketnamen, jedoch mit JUnit-Semantik.Beachten Sie, dass diese IDEs Tests für Methoden in generieren
odp.proj
und den entsprechenden Ordner für die Testmethoden erstellen, die nicht vorhanden sind.quelle
Wenn ich dies in IntelliJ mache, sieht mein Quellbaum folgendermaßen aus:
quelle
Es hängt wahrscheinlich ein wenig von Ihren Motiven ab, sie nicht anzuzeigen, aber wenn der einzige Grund darin besteht, dass Sie die öffentliche Schnittstelle nicht mit Dingen verschmutzen möchten, die nur zum Testen (oder einer anderen internen Sache) bestimmt sind, würde ich die Methoden in a einfügen separate öffentliche Schnittstelle und lassen Sie die Konsumenten der "versteckten" Methoden diese Schnittstelle verwenden. Es wird andere nicht davon abhalten, die Schnittstelle zu verwenden, aber ich sehe keinen Grund, warum Sie sollten.
Befolgen Sie für Unit-Tests und wenn es möglich ist, das Los nicht neu zu schreiben, die Vorschläge, dasselbe Paket zu verwenden.
quelle
Wie andere erklärt haben, gibt es in Java kein "Unterpaket": Alle Pakete sind isoliert und erben nichts von ihren Eltern.
Eine einfache Möglichkeit, von einem anderen Paket aus auf geschützte Klassenmitglieder zuzugreifen, besteht darin, die Klasse zu erweitern und die Mitglieder zu überschreiben.
Zum Beispiel, um
ClassInA
im Paket zuzugreifena.b
:Erstellen Sie in diesem Paket eine Klasse, die die folgenden Methoden überschreibt
ClassInA
:Auf diese Weise können Sie die überschreibende Klasse anstelle der Klasse im anderen Paket verwenden:
Beachten Sie, dass dies nur für geschützte Mitglieder funktioniert, die für Erweiterungsklassen sichtbar sind (Vererbung), und nicht für paketprivate Mitglieder, die nur für Unter- / Erweiterungsklassen innerhalb desselben Pakets sichtbar sind. Hoffentlich hilft das jemandem!
quelle
Die meisten Antworten hier haben angegeben, dass es in Java kein Unterpaket gibt, aber das ist nicht genau. Dieser Begriff wurde bereits in Java 6 und wahrscheinlich weiter hinten in der Java-Sprachspezifikation verwendet (es scheint keine frei zugängliche Version des JLS für frühere Java-Versionen zu geben). Die Sprache um Unterpakete hat sich im JLS seit Java 6 nicht wesentlich geändert.
Java 13 JLS :
Das Unterpaketkonzept ist relevant, ebenso wie die Durchsetzung von Namensbeschränkungen zwischen Paketen und Klassen / Schnittstellen:
Diese Namensbeschränkung ist jedoch die einzige Bedeutung, die Unterpakete durch die Sprache erhalten:
In diesem Zusammenhang können wir die Frage selbst beantworten. Da es explizit keine spezielle Zugriffsbeziehung zwischen einem Paket und seinem Unterpaket oder zwischen zwei verschiedenen Unterpaketen eines übergeordneten Pakets gibt, gibt es innerhalb der Sprache keine Möglichkeit, eine Methode für zwei verschiedene Pakete auf die angeforderte Weise sichtbar zu machen. Dies ist eine dokumentierte, absichtliche Entwurfsentscheidung.
Entweder kann die Methode veröffentlicht werden und alle Pakete (einschließlich
odp.proj
undodp.proj.test
) können auf die angegebenen Methoden zugreifen, oder die Methode kann als Paket privat gemacht werden (Standardsichtbarkeit), und der gesamte Code, der für den direkten Zugriff darauf erforderlich ist, muss eingegeben werden das gleiche (Unter-) Paket wie die Methode.In Java ist es jedoch sehr üblich, den Testcode im selben Paket wie den Quellcode abzulegen, jedoch an einem anderen Ort im Dateisystem. Im Maven- Build-Tool besteht die Konvention beispielsweise darin, diese Quell- und Testdateien in
src/main/java/odp/proj
bzw. abzulegensrc/test/java/odp/proj
. Wenn das Build-Tool dies kompiliert, landen beide Dateigruppen imodp.proj
Paket, aber nur diesrc
Dateien sind im Produktionsartefakt enthalten. Die Testdateien werden nur zur Erstellungszeit verwendet, um die Produktionsdateien zu überprüfen. Mit diesem Setup kann der Testcode frei auf jeden privaten oder geschützten Paketcode des getesteten Codes zugreifen, da er sich im selben Paket befindet.In dem Fall, in dem Sie Code-Freigabe für Unterpakete oder Geschwisterpakete wünschen, der nicht der Test- / Produktionsfall ist, besteht eine Lösung, die einige Bibliotheken verwendet haben, darin, diesen freigegebenen Code als öffentlich zu kennzeichnen, aber zu dokumentieren, dass er für die interne Bibliothek bestimmt ist nur benutzen.
quelle
Ohne den Zugriffsmodifikator vor die Methode zu stellen, sagen Sie, dass es sich um ein privates Paket handelt.
Schauen Sie sich das folgende Beispiel an.
quelle
Mit der PackageVisibleHelper-Klasse, die vor dem Einfrieren von PackageVisibleHelperFactory privat bleibt, können wir die Methode launchA (von PackageVisibleHelper) überall aufrufen :)
quelle