反复访问Java类中的静态变量

时间:2009-08-10 20:22:55

标签: java reflection initialization

我没有别的选择,只能通过反射访问一组我无法修改的类。 但是,使用下面主方法中显示的方法会抛出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 !!!”之前

3 个答案:

答案 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 );
    }
}

静态声明需要(前面)构造函数。