反射性地访问 Java 类中的静态变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1256996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reflectively accessing a static variable in a Java class
提问by Andrew
I've been given no other choice but to access a set of classes, which I cannot modify, with this structure through reflection. Using the method shown in the main method below however, throws a NullPointerException. The null pointer being "table" in the constructor when f1.get(null) is called.
我别无选择,只能通过反射使用此结构访问一组我无法修改的类。但是,使用下面主要方法中显示的方法会引发 NullPointerException。调用 f1.get(null) 时,构造函数中的空指针为“表”。
I am unable to instantiate the classes beforehand because the only constructor is the one shown, which is private. So there is no way for me to explicitly set table either.
我无法事先实例化这些类,因为唯一的构造函数是显示的那个,它是私有的。所以我也没有办法明确设置表格。
Anyone know of a way for me to reflectively call Legacy.A?
任何人都知道一种让我反思地调用 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);
}
}
In before "Reflection == BAD!!!"
在“反射==坏!!!”之前
回答by starblue
The order of the static initializers is wrong, table must come before the constructor calls.
静态初始化器的顺序是错误的,表必须在构造函数调用之前出现。
This is the reason that you get the exception when the class is loaded and initialized. This has nothing to do with reflection.
这就是在加载和初始化类时出现异常的原因。这与反射无关。
回答by Aviad Ben Dov
Since this is confusing, I would write it like this:
由于这令人困惑,我会这样写:
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);
}
}
This way, even if the members change location (due to refactoring, line alignment or whatever) the code will always work.
这样,即使成员更改位置(由于重构、行对齐或其他原因),代码也将始终有效。
回答by Steve B.
I tried this, because I couldn't see what was wrong with your example. It worked if I reordered the declarations:
我试过这个,因为我看不出你的例子有什么问题。如果我重新排序声明,它会起作用:
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 );
}
}
The static declarations need the (preceding) constructor.
静态声明需要(前面的)构造函数。

