我没有别的选择,只能通过反射访问一组我无法修改的类。 但是,使用下面主方法中显示的方法会抛出NullPointerException。调用f1.get(null)时,空指针在构造函数中为“table”。
我无法预先实例化类,因为唯一的构造函数是显示的,它是私有的。因此,我无法明确设置表格。
任何人都知道我可以反思地称呼Legacy.A吗?
public class Legacy {
public static final Legacy A = new Legacy("A");
public static final Legacy B = new Legacy("B");
private String type0;
private static Map<String, Legacy> table = new HashMap<String, Legacy>();
private Legacy(String id) {
type0 = id;
table.put(type0, this);
}
public static void main(String[] args) throws Exception {
Field f1 = Legacy.class.getDeclaredField("A");
Object o = f1.get(null);
}
}
在“Reflection == BAD !!!”之前
答案 0 :(得分:7)
静态初始化程序的顺序是错误的,表必须在构造函数调用之前。
这是在加载和初始化类时获得异常的原因。这与反射无关。
答案 1 :(得分:4)
由于这令人困惑,我会这样写:
public class Legacy {
static {
table = new HashMap<String, Legacy>();
A = new Legacy("A");
B = new Legacy("B");
}
public static final Legacy A;
public static final Legacy B;
private String type0;
private static Map<String, Legacy> table;
private Legacy(String id) {
type0 = id;
table.put(type0, this);
}
public static void main(String[] args) throws Exception {
Field f1 = Legacy.class.getDeclaredField("A");
Object o = f1.get(null);
}
}
这样,即使成员更改位置(由于重构,行对齐等),代码也始终有效。
答案 2 :(得分:0)
我试过这个,因为我看不出你的例子有什么问题。如果我重新排序声明,它就有用了:
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Legacy {
private String type0;
private static Map< String, Legacy > table = new HashMap< String, Legacy >();
private Legacy( String id ) {
type0 = id;
table.put( type0, this );
}
public static final Legacy A = new Legacy( "A" );
public static final Legacy B = new Legacy( "B" );
public static void main( String[] args ) throws Exception {
Field f1 = Legacy.class.getDeclaredField( "A" );
Object o = f1.get( null );
}
}
静态声明需要(前面)构造函数。