在方法调用和参数传入的情况下,是否保证Java评估顺序 [英] Is Java evaluation order guaranteed in this case of method call and arguments passed in

查看:85
本文介绍了在方法调用和参数传入的情况下,是否保证Java评估顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JLS 15.7上进行了一些阅读. 4 15.12.4.2 ,但不能保证不会有任何编译器/运行时优化更改方法参数的求值顺序.

I did some reading up on JLS 15.7.4 and 15.12.4.2, but it doesn't guarantee that there won't be any compiler/runtime optimization that would change the order in which method arguments are evaluated.

假设以下代码:

public static void main (String[] args) {
  MyObject obj = new MyObject();
  methodRelyingOnEvalOrder(obj, obj.myMethod());
}

public static Object methodRelyingOnEvalOrder(MyObject obj, Object input) {
  if (obj.myBoolean())
    return null;
  else
    return input;
}

是否保证编译器或运行时不会进行如下错误的优化?这种优化看似正确,但在评估顺序很重要时是错误的.

Is it guaranteed that the compiler or runtime will not do a false optimization such as the following? This optimization may appear correct, but it is wrong when the order of evaluation matters.

如果调用obj.myMethod更改了obj.myBoolean将返回的值,则至关重要的是,首先调用obj.myMethod,因为methodRelyingOnEvalOrder要求首先进行此更改.

In the case where calling obj.myMethod alters the value that will be returned by obj.myBoolean, it is crucial that obj.myMethod be called first as methodRelyingOnEvalOrder requires this alteration to happen first.

//*******************************
//Unwanted optimization possible:
//*******************************
public static void main (String[] args) {
  MyObject obj = new MyObject();
  methodRelyingOnEvalOrder(obj);
}

public static Object methodRelyingOnEvalOrder(MyObject obj) {
  if (obj.myBoolean())
    return null;
  else
    return obj.myMethod();
}
//*******************************

如果可能,请显示一些支持您答案的资源或Java文档.

If possible, please show some sources or Java documentation that supports your answer.

注意:请不要要求重写代码.这是我质疑评估顺序保证和编译器/运行时优化保证的特定情况. obj.myMethod的执行必须在main方法中进行.

Note: Please do not ask to rewrite the code. This is a specific case where I am questioning the evaluation order guarantee and the compiler/runtime optimization guarantee. The execution of obj.myMethod must happen in the main method.

推荐答案

您引用的JLS位(15.7.4)可以保证:

The bit of the JLS you referred to (15.7.4) does guarantee that:

每个参数表达式似乎在其右侧任何参数表达式的任何部分之前都经过了充分评估.

Each argument expression appears to be fully evaluated before any part of any argument expression to its right.

以及15.12.4.2:

and also in 15.12.4.2:

然后使用参数值继续评估,如下所述.

Evaluation then continues, using the argument values, as described below.

出现"部分可以进行一些优化,但不能可见.所有参数都在先评估然后继续"之前被评估的事实表明,在执行该方法之前,这些参量实际上已经被完全评估. (或者至少是可见的结果.)

The "appears to" part allows for some optimization, but it must not be visible. The fact that all the arguments are evaluated before "evaluation then continues" shows that the arguments are really fully evaluted before the method executes. (Or at least, that's the visible result.)

例如,如果您有以下代码:

So for example, if you had code of:

int x = 10;
foo(x + 5, x + 20);

可能进行优化以同时评估x + 5x + 20:您无法检测到这种情况.

it would be possible to optimize that to evaluate both x + 5 and x + 20 in parallel: there's no way you could detect this occurring.

但是在给出的情况下,您能够检测到对obj.myBoolean()的调用之后发生的对obj.myMethod的调用,因此将不会完全是有效的优化.

But in the case you've given, you would be able to detect the call to obj.myMethod occurring after the call to obj.myBoolean(), so that wouldn't be a valid optimization at all.

简而言之:您可以假设一切都将以明显的方式执行.

In short: you're fine to assume that everything will execute in the obvious way here.

这篇关于在方法调用和参数传入的情况下,是否保证Java评估顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆