假设您有此代码段
private final Set set = new HashSet() {{ add(1); }};
SomeConstructor() {
printSet();
}
long printSet() {
new Thread(() -> {System.out.println(set)}).start();
}
例如,如果编译器决定使其看起来像
private final Set set;
SomeConstructor() {
printSet();
set = new HashSet() {{ add(1); }};
}
这将是一个问题,因为calculateWaitTime()创建一个新的线程,可能会将该集视为null或者其中没有1。
再次提出这个问题,重新排序是否可行?或者在构造函数之外初始化的所有最终字段在构造函数之前初始化,或者至少总是由编译器移动到构造函数的顶部
答案 0 :(得分:2)
final
字段不可能。
17.5.2在施工期间阅读最终字段
读取构造该对象的线程内对象的最终字段 有关在构造函数中初始化该字段的命令 通常发生在规则之前。如果在构造函数中设置字段后发生读取, 它会看到最终字段分配的值,否则会看到默认值。
但是你也可以看到它不能保证使用反射的后续final
字段修改。有关详细信息,请参阅17.5.3。