修改Java中的最终字段 [英] Modifying final fields in Java
问题描述
让我们从一个简单的测试用例开始:
Let's start with a simple test case:
import java.lang.reflect.Field;
public class Test {
private final int primitiveInt = 42;
private final Integer wrappedInt = 42;
private final String stringValue = "42";
public int getPrimitiveInt() { return this.primitiveInt; }
public int getWrappedInt() { return this.wrappedInt; }
public String getStringValue() { return this.stringValue; }
public void changeField(String name, Object value) throws IllegalAccessException, NoSuchFieldException {
Field field = Test.class.getDeclaredField(name);
field.setAccessible(true);
field.set(this, value);
System.out.println("reflection: " + name + " = " + field.get(this));
}
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
Test test = new Test();
test.changeField("primitiveInt", 84);
System.out.println("direct: primitiveInt = " + test.getPrimitiveInt());
test.changeField("wrappedInt", 84);
System.out.println("direct: wrappedInt = " + test.getWrappedInt());
test.changeField("stringValue", "84");
System.out.println("direct: stringValue = " + test.getStringValue());
}
}
任何人都在猜测将作为输出打印的内容(显示在底部,以免立即破坏惊喜。)
Anybody care to guess what will be printed as output (shown at the bottom as to not spoil the surprise immediately).
问题是:
- 为什么原始和包装整数的行为有所不同?
- 为什么反射与直接访问会返回不同的结果?
- 困扰我的那个大多数 - 为什么String的行为类似于原始
int
而不是像整数
?
- Why do primitive and wrapped integer behave differently?
- Why does reflective vs direct access return different results?
- The one that plagues me most - why does String behave like primitive
int
and not likeInteger
?
结果(java 1.5):
Results (java 1.5):
reflection: primitiveInt = 84
direct: primitiveInt = 42
reflection: wrappedInt = 84
direct: wrappedInt = 84
reflection: stringValue = 84
direct: stringValue = 42
推荐答案
编译时常量是内联的(在javac编译时)。参见JLS,特别是15.28定义了一个常量表达式,13.4.9讨论了二进制兼容性或最终字段和常量。
Compile-time constants are inlined (at javac compile-time). See the JLS, in particular 15.28 defines a constant expression and 13.4.9 discusses binary compatibility or final fields and constants.
如果你将字段设为非final或者指定一个非编译时间常量,该值不是内联的。例如:
If you make the field non-final or assign a non-compile time constant, the value is not inlined. For instance:
private final String stringValue = null!= null?:42;
private final String stringValue = null!=null?"": "42";
这篇关于修改Java中的最终字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!