通过反射访问Java静态最终变量值

通过反射访问Java静态最终变量值,java,reflection,Java,Reflection,Java静态final类变量的值可以通过反射检索吗?我想这取决于类型和编译器(仔细想想,最好不要!)。Sun的编译器内联了基本常量,但我不知道它们是否从类中完全删除了该项。我会知道的 编辑:是的,即使它们是内联的,您仍然可以访问它们。测试等级: public class ReflectionConstantTest { private static final int CONST_INT = 100; private static final String CONST_STRIN

Java静态final类变量的值可以通过反射检索吗?

我想这取决于类型和编译器(仔细想想,最好不要!)。Sun的编译器内联了基本常量,但我不知道它们是否从类中完全删除了该项。我会知道的

编辑:是的,即使它们是内联的,您仍然可以访问它们。测试等级:

public class ReflectionConstantTest {
    private static final int CONST_INT = 100;
    private static final String CONST_STRING = "String";
    private static final Object CONST_OBJECT = new StringBuilder("xyz");
    public static void main(String[] args) throws Exception {
        int testInt = CONST_INT;
        String testString = CONST_STRING;
        Object testObj = CONST_OBJECT;
        for (Field f : ReflectionConstantTest.class.getDeclaredFields()) {
            f.setAccessible(true);
            System.out.println(f.getName() + ": " + f.get(null));
        }
    }
}
输出:

CONST_INT: 100 CONST_STRING: String CONST_OBJECT: xyz 您可以看到
CONST\u INT
是内联的,但是
CONST\u STRING
CONST\u OBJECT
(当然)不是内联的。然而,
CONST\u INT
仍然可以反射地使用。

是。(只是没有静态的、实例的东西。它是静态的、非实例的。)


(包括标准警告:大多数使用反射是个坏主意)

如果项目中允许使用开源库,则可以使用

在另一个类中,您可以使用:

Object value = FieldUtils.readDeclaredStaticField(Test.class, "CONSTANT");
System.out.println(value);

您将在控制台中看到“myConstantValue”。

仅获取名称和值不需要setAccessible(true)。下面是一个有用的示例,您需要处理接口中声明的常量,并需要符号名:

interface Code {
   public static final int FOO = 0;
   public static final int BAR = 1;
}

...

try {
   for (Field field : Code.class.getDeclaredFields()) {
      String name = field.getName();
      int value = field.getInt(null);
      System.out.println(name + "=" + value);
   }
}
catch (IllegalAccessException e) {
   System.out.println(e);
}

这解决了我的问题,谢谢!我很好奇为什么我们必须叫f.setAccessible(true)。静态修饰符一开始就不可访问有什么意义?@gsingh2011:唯一必要的原因是证明即使是私有常量也可以通过反射访问(您可能会注意到示例中的三个常量声明为私有)。公共常量不需要设置为可访问,因为它们已经可以访问了。啊,我明白了。我刚刚意识到出现问题是因为我没有为字段提供公共/私有修饰符,然后将代码重构成包。谢谢你的回复。
Object value = FieldUtils.readDeclaredStaticField(Test.class, "CONSTANT");
System.out.println(value);
interface Code {
   public static final int FOO = 0;
   public static final int BAR = 1;
}

...

try {
   for (Field field : Code.class.getDeclaredFields()) {
      String name = field.getName();
      int value = field.getInt(null);
      System.out.println(name + "=" + value);
   }
}
catch (IllegalAccessException e) {
   System.out.println(e);
}