Java 8表达式评估序列

时间:2016-05-27 18:58:54

标签: java java-8

我有一个像

这样的案例
MyClass.invoke( anObject.setSystem() );

是否保证在加载MyClass之前调用anObject.setSystem()?由于MyClass的初始化代码取决于anObject.setSystem()的结果。

它正在运行Java 8.任何建议/提示将不胜感激。非常感谢

1 个答案:

答案 0 :(得分:1)

将加载

MyClass,并在调用MyClass.invoke()之前初始化其所有静态字段和静态初始值设定项。

请参阅JLS 12.14.1

  

类或接口类型T将在第一次出现以下任何一个之前立即初始化:      

  • T是一个类,创建了一个T实例。   
  • T是一个类,调用T声明的静态方法。 < ------------就在这里   
  • 分配由T声明的静态字段。   
  • 使用由T声明的静态字段,该字段不是常量变量(第4.12.4节)。   
  • T是顶级类(第7.6节),并且执行在词典中嵌套在T(第8.1.3节)内的断言语句(第14.10节)。

  • 修改 感谢@Holger和@ gigi的评论,仍然存在一个问题,即触发加载类的调用是在评估传递给它的参数表达式之前还是之后发生的。我认为答案就是JLS 15.12.4,其中说明了

      

    在运行时,方法调用需要五个步骤。首先,可以计算目标参考。其次,评估参数表达式。第三,检查要调用的方法的可访问性。第四,找到要执行的方法的实际代码。第五,创建新的激活帧,必要时执行同步,并将控制转移到方法代码。

    参数表达式的评估(步骤2)发生在执行方法的代码所在之前(步骤4,这可能导致类被加载并静态初始化),然后,在最后一步中,才是调用静态方法。