我使用默认初始化类字段,如下所示。我想字段将按如下顺序初始化:
class NormalInit {
int i = 3;
LocalDate h = LocalDate.now();
public int year = h.getYear(); // is it safe?
}
我的问题:
(1) 我对序列的假设正确吗(这是由java或jvm规范保证的吗)?
(2) 这种初始化是否存在常见的故障/陷阱?
应该可以。根据java,内存模型和语言规范语句在一个线程中从上到下进行评估。
初始化块的顺序https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4
4.执行该类的实例初始化器和实例变量初始化器,将实例变量初始化程序的值按从左到右的顺序分配给相应的实例变量,这些值在该类的源代码中以文本形式出现。如果这些初始化程序中的任何一个的执行导致异常,则不处理进一步的初始化程序,并且该过程突然完成,出现相同的异常
此链接适用于先发生后解释:https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4.5
如果x和y是同一线程的操作,并且x按程序顺序位于y之前,则hb(x,y)。
从技术上讲,对i
和h
的分配可以重新排序,但在您的情况下,它不会对程序的语义产生任何影响。
h
依赖于year
,JVM不会重新排序这些分配。
但是i
没有依赖关系,所以JVM可以在构建的任何时刻放入它的init。