简体   繁体   English

Java 8 表达式求值序列

[英]Java 8 expression evaluation sequence

I have a case like我有一个案例

MyClass.invoke( anObject.setSystem() );

Is there a guarantee that anObject.setSystem() will be called before MyClass is loaded?是否保证在加载 MyClass 之前会调用anObject.setSystem() As the initialization code of MyClass depends on the result of anObject.setSystem() .由于 MyClass 的初始化代码取决于anObject.setSystem()的结果。

It is running with Java 8. Any suggestions/hints would be appreciated.它与 Java 8 一起运行。任何建议/提示将不胜感激。 Many thanks非常感谢

MyClass will be loaded and all of its static fields and static initializers will be initialized before MyClass.invoke() is called. MyClass将被加载,并且它的所有静态字段和静态初始值设定项将在MyClass.invoke()之前被初始化。

See JLS 12.14.1JLS 12.14.1

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:

  • T is a class and an instance of T is created. T 是一个类,并且创建了一个 T 的实例。
  • T is a class and a static method declared by T is invoked. T 是一个类,并且调用了由 T 声明的静态方法。 <------------ right here <------------就在这里
  • A static field declared by T is assigned.分配了由 T 声明的静态字段。
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).使用 T 声明的静态字段,该字段不是常量变量(第 4.12.4 节)。
  • T is a top level class (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed. T 是顶级类(第 7.6 节),并且执行在词法上嵌套在 T(第 8.1.3 节)中的 assert 语句(第 14.10 节)。

  • EDIT Thanks to @Holger and @gigi's comments, there was still the question as to whether the invocation that triggers the loading of the class occurs before or after the evaluation of the argument expression passed into it.编辑感谢@Holger 和@gigi 的评论,仍然存在一个问题,即触发类加载的调用是发生在传递给它的参数表达式的评估之前还是之后。 I think the answer to that is in JLS 15.12.4 , which states,我认为答案在JLS 15.12.4 中,其中指出,

    At run time, method invocation requires five steps.在运行时,方法调用需要五个步骤。 First, a target reference may be computed.首先,可以计算目标参考。 Second, the argument expressions are evaluated.其次,评估参数表达式。 Third, the accessibility of the method to be invoked is checked.第三,检查要调用的方法的可访问性。 Fourth, the actual code for the method to be executed is located.第四,找到要执行的方法的实际代码。 Fifth, a new activation frame is created, synchronization is performed if necessary, and control is transferred to the method code.第五,创建新的激活帧,必要时执行同步,并将控制转移到方法代码。

    The evaluation of argument expressions (step 2) occurs before the code to execute the method is located, (step 4, which probably results in the class being loaded and statically initialized) and only then, in the final step, is the static method invoked.参数表达式的求值(第 2 步)发生在定位执行该方法的代码之前(第 4 步,这可能导致类被加载和静态初始化),然后才在最后一步中调用静态方法.

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM