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