我知道这是一个糟糕的代码设计,但作为一个临时的黑客......
我需要访问私有映射,其中值是静态嵌套类的初始化。在下面的示例中,我想从不同的包中访问myMap的每个值。
package belongs.to.someone.else
public class SOExample {
private Map<String, NestedClass> myMap;
static class NestedClass {
final int data;
NestedClass(final int data) {
this.data = data;
}
}
public void populateMyMap(){
for(int i=0; i<100; i++){
this.myMap.put(Integer.toString(i), new NestedClass(i));
}
}
}
但是在尝试将SOExample.myMap字段设置为可访问时,我似乎遇到了鸡和蛋的问题。对于最后一个语句中的SOExample.NestedClass
值,我收到“无法从包外访问”错误。
package belongs.to.me
public class SOExampleMyPackage {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
SOExample example = new SOExample();
example.populateMyMap();
// Make the example.myMap field accessible
Field f = example.getClass().getDeclaredField("myMap");
f.setAccessible(true);
// Next line throws error
Map<String, SOExample.NestedClass> myMapHere = (Map<String, SOExample.NestedClass>) f.get(example);
}
}
我很感激有关如何解决这个问题的任何想法。
答案 0 :(得分:1)
您收到编译时错误,因为无法访问嵌套类。
你唯一能做的就是避免使用这个类的引用:
Field f = example.getClass().getDeclaredField("myMap");
f.setAccessible(true);
Map map = (Map) f.get(example);
Object obj = map.get("1");
您可以使用反射访问obj
实例上的字段并调用方法。
答案 1 :(得分:0)
@AdamSkywalker提供了正确的方法。为了完整起见,我发布了最后的工作示例。
public class SOExampleMyPackage {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
SOExample example = new SOExample();
example.populateMyMap();
// Make the example.myMap field accessible
Field f = example.getClass().getDeclaredField("myMap");
f.setAccessible(true);
/////
//SOLUTION start
/////
Map<String, Object> myMapHere = (Map<String, Object>) f.get(example);
// Loop through entries and reflect out the values
Map<String, Integer> finalMap = new HashMap<String, Integer>();
for (String k: myMapHere.keySet()){
Field f2 = myMapHere.get(k).getClass().getDeclaredField("data");
f2.setAccessible(true);
finalMap.put(k, (Integer) f2.get(myMapHere.get(k)));
}
/////
//SOLUTION end
/////
// Test it all
for (String k: finalMap.keySet()){
System.out.println("Key: " + k + " Value: " + finalMap.get(k));
}
}
}