Wie der Zugriff auf package-private-Klasse aus einer Klasse, in der einige andere Paket?
Habe ich folgende classses
Hello.java
package speak.hello;
import java.util.Map;
import speak.hi.CustomMap;
import speak.hi.Hi;
public class Hello {
private Hi hi;
Hello(Hi hi) {
this.hi = hi;
}
public String sayHello() {
return "Hello";
}
public String sayHi() {
return hi.sayHi();
}
public Map<String, Object> getMap() {
return hi.getMap();
}
public void clearMap() {
hi.getMap().clear();
}
public void discardMap() {
CustomMap map = (CustomMap) hi.getMap();
map.discard();
}
public static void main(String[] args) {
Hello hello = new Hello(new Hi());
System.out.println(hello.sayHello());
System.out.println(hello.sayHi());
System.out.println(hello.getMap());
hello.clearMap();
System.out.println("--");
hello.discardMap();
}
}
Hi.java
package speak.hi;
import java.util.HashMap;
import java.util.Map;
public class Hi {
public String sayHi() {
return "Hi";
}
public Map<String, Object> getMap() {
return new CustomMap<String, Object>();
}
}
CustomMap.java
package speak.hi;
import java.util.HashMap;
public class CustomMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = -7979398843650044928L;
public void discard() {
System.out.println("Discarding Map");
this.clearCache();
this.clear();
}
@Override
public void clear() {
System.out.println("Clearing Map");
super.clear();
}
private void clearCache() {
System.out.println("Clearing Map");
}
}
Dies funktioniert gut, bis ich entfernen public
zugriffsspezifizierer von CustomMap
package speak.hi;
import java.util.HashMap;
class CustomMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = -7979398843650044928L;
public void discard() {
System.out.println("Discarding Map");
this.clearCache();
this.clear();
}
@Override
public void clear() {
System.out.println("Clearing Map");
super.clear();
}
private void clearCache() {
System.out.println("Clearing Map");
}
}
Compiler schreit, dass
Art sprechen.hi.CustomMap ist nicht sichtbar
Nun, Wenn ich keine Optionen ändern speak.hi.CustomMap
(Dritten Glas etc..) gibt es eine Möglichkeit, ich könnte noch CustomMap
aus speak.hello.Hello
?
Eine Möglichkeit, die ich kenne, ist, sich zu bewegen speak.hello.Hello
zu speak.hi.Hello
als Jetzt Hallo ist im Paket speak.hi
Zugriff auf package-private Class Hi
Gibt es eine andere Möglichkeit, dies zu tun ? Mit der spiegelung vielleicht ?
BEARBEITEN :Aktualisiert, mit zusätzlichen details auf Wunsch von @StephenC
InformationsquelleAutor Prashant Bhate | 2011-11-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ja. Reflexion kann verwendet werden, zu umgehen, um den Java-Regeln für den Zugang, wenn Ihre Anwendung hat Ihre volle Berechtigung.
Zum Beispiel, um auf eine
private
Feld eines Objekts aus einer anderen Klasse haben, müssen Sie zu:Class
Objekt.Class.getDeclaredField(...)
Methode, um einenField
Objekt für das Feld.Field.setAccessible(true)
zu deaktivieren, den Zugriff zu überprüfen.Class.getField(object, Field)
zu bekommen, das Feld ist-Wert (oder boxed-Wert, wenn es ein primitiver Typ).Wenn die Klasse selbst ist nicht zugänglich, müssen Sie sicherstellen, dass Sie don ' T beziehen sich auf die Klassen-Bezeichner im Quelltext ... 'cos, das führt zu einem Kompilierungsfehler. Weisen Sie stattdessen den Verweis auf (sagen wir) variable vom Typ
Object
oder irgendeiner anderen sichtbaren Supertyp, und ausführen bestimmter Vorgänge auf die Instanz nachdenklich.Als Sie sich vorstellen können, das ist mühsam und fehleranfällig. Sie würde geraten werden, einen besseren Weg finden, wie:
(Im Allgemeinen, wenn Sie haben zu brechen, öffnen Sie eine Abstraktion ist, dann stimmt etwas nicht-entweder mit der Abstraktion selbst oder die Art und Weise Sie es verwenden.)
Schließlich sollte ich hinzufügen, dass nicht vertrauenswürdiger code ist (sein sollte) laufen in einer sandbox, das blockiert die Verwendung der key-reflektierende Operationen.
InformationsquelleAutor Stephen C
Folgende Methode Ruft
default
scoped-Methode der Klasse mit der spiegelungInformationsquelleAutor Prashant Bhate
Nicht möglich. Das Sicherheitsmodell ist das : ein Modell für Sicherheit zu sorgen 🙂 Wenn du einen Klasse Hallo zusammen und liefert Sie an Kunden mit privatem Zugang, würden Sie nicht möchte, dass Sie in der Lage sein zu umgehen, Ihre Einschränkungen, würden Sie?
Die Java-zugriffsmodifizierer sind NICHT in Erster Linie um die Sicherheit. Sie sind über die Aufrechterhaltung der Abstraktion Grenzen. (Tipp: wenn Sie wissen, was Sie tun, können Sie mithilfe von reflektion zu betrachten, und die Dinge ändern, die den Zugriff Regeln, die sagen, Sie können nicht.)
InformationsquelleAutor solendil
Ich nicht empfehlen für die Verwendung von nicht-API-Klassen, wie Sie ändern könnte in einer zukünftigen version und kann brechen Sie Ihre code.
Wie haben Sie herausfinden, über diese Klasse? Ist es ein Open-Source-Bibliothek?
Versuchen, Kontakt mit den Autoren der Bibliothek, erzählen Sie Ihren Fall und einen Weg finden, mit Ihnen eine öffentliche API. Wenn es ein open-source-Bibliothek, die Sie Ihnen helfen könnten, indem Sie einen patch.
InformationsquelleAutor Puce
Ich würde denken, dass wenn die Autoren eine Bibliothek, nicht eine bestimmte Klasse Teil der öffentlichen API, es ist, weil Sie nicht möchten, dass andere Leute, die es. Sie sollten das respektieren die Entscheidung, auch wenn Sie brechen es mit der spiegelung. Mit private API ist einfach schlechte Programmierung.
InformationsquelleAutor JeremyP
Hinzufügen dieser Lösung, der Vollständigkeit halber.
Eine Möglichkeit, die ich kenne, ist zu bewegen, zu sprechen.Hallo.Hallo, zu sprechen.hi.Hallo, da Jetzt Hallo, im Paket zu sprechen.hi, es kann Zugriff auf package-private Class Hi
InformationsquelleAutor Prashant Bhate
Kann es nicht möglich sein, weil:
Klasse :
Zugänglich-Klasse aus demselben Paket?
Zugänglich-Klasse von verschiedenen Paket?
InformationsquelleAutor Chandra Sekhar
1. Klasse ist im Paket ein.b.c.class1 aber class1 ist die private wie auch die abstrakte
2. Klasse ist im Paket ein.b.c.class2 extends class1 aber class2 ist öffentlich
3. Klasse ist im Paket-x.y.z.class3
Damit Zugang class1 in der Klasse 3 schreiben Sie etwas wie:-
Klasse baseClass = (new class2()).getClass();
und verwenden Sie die Instanz der übergeordneten Klasse dann benutzen:-
baseClass.getSuperClass();
und verwenden Sie es, wo immer Sie wollen.
Dann aber wieder baseclass gemacht wurde, abstrakte und private für einen Grund daher nicht ratsam, dies zu tun, aber dann wieder diese Lösung kann verwendet werden als ein workaround.
InformationsquelleAutor Sumit Kumar Saha
Nicht Möglich ist, können Sie nicht Ihre Hi-Klasse als privat.
Danke. Ich weiß, dass.
Das ist nur wahr für die top-level-Klassen.
InformationsquelleAutor Jwalin Shah
Ich glaube, standardmäßig ist die Klasse "Standard" (package-private ist, kann man sagen), NICHT "privat". Also es kann zugegriffen werden mit der gleichen Paket.
Außerdem, Sie NICHT machen *top-level-Klasse Private in Java.
Und wenn Sie möchten, machen einen Klasse Standard und immer noch Zugriff auf es in einem anderen Paket, was wird dann sein, die Zwecke, die Zugriffsbezeichner (Modifikatoren) ??
muss man entweder machen, Klasse öffentlich oder zu bewegen, um das gleiche Paket.
aber ich denke, hier reden wir nicht über private (nested) Klassen.
Deine Aussage sagt: "jede Klasse private in Java"
ich habe bereits bearbeitet @Herr Puce.
Nur um zu bestätigen, ich meinte "package private" = "default" - top-level-Klasse.
InformationsquelleAutor gprathour