如何从其他包中的类访问包私有类?
问题内容:
我有以下课程
你好
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();
}
}
嗨.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");
}
}
直到我public
从中删除访问说明符之前,这都可以正常工作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");
}
}
编译器大喊
类型speak.hi.CustomMap不 可见
现在,如果我没有修改的选项speak.hi.CustomMap
(第三方jar等),还有什么我可以使用CustomMap
的方法speak.hello.Hello
吗?
我知道的一个选项是转到speak.hello.Hello
,speak.hi.Hello
因为Hello已在程序包中,speak.hi
它可以访问程序包私有类。Hi
还有其他方法吗?也许使用反射?
编辑 :按@StephenC的要求更新了其他详细信息
问题答案:
以下default
方法使用反射调用作用域类方法
public void discardMap() {
//CustomMap map = (CustomMap) hi.getMap();
//map.discard();
try {
Object o =hi.getClass().getMethod("getMap").invoke(hi);
Method m = o.getClass().getMethod("discard");
m.setAccessible(true);
m.invoke(o);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}