(给ImportNew加星标,提高Java技能)
编译:ImportNew/唐尤华
shipilev.net/jvm/anatomy-quarks/14-constant-variables/
1. 写在前面
“JVM 解剖公园”是一个持续更新的系列迷你博客,阅读每篇文章一般需要5到10分钟。限于篇幅,仅对某个主题按照问题、测试、基准程序、观察结果深入讲解。因此,这里的数据和讨论可以当轶事看,不做写作风格、句法和语义错误、重复或一致性检查。如果选择采信文中内容,风险自负。
Aleksey Shipilёv,JVM 性能极客
推特 @shipilev
问题、评论、建议发送到 aleksey@shipilev.net"">aleksey@shipilev.net
2. 问题
实例中 final 字段是不是常量?
3. 理论
假如你读过 Java 语言规范中关于 final 变量语义的描述,会发现一段诡异的描述:
>
常量(Constant Variable)指使用常量表达式(§15.28)初始化的 final 变量,其类型为原始类型或 String。一个变量否为常量可能对类初始化(§12.4.1)、二进制兼容性(§13.1, §13.4.9) 和明确赋值(§16)产生影响。
— Java 语言规范 4.12.4
>
上述影响能够通过实验观察吗?
4. 实验
思考下面代码的输出是什么?
import java.lang.reflect.Field;
public class ConstantValues {
final int fieldInit = 42;
final int instanceInit;
final int constructor;
{
instanceInit = 42;
}
public ConstantValues() {
constructor = 42;
}
static void set(ConstantValues p, String field) throws Exception {
Field f = ConstantValues.class.getDeclaredField(field);
f.setAccessible(true);
f.setInt(p, 9000);
}
public static void main(String... args) throws Exception {