函数的增量被+ =覆盖

Hit*_*hal 17 java increment variable-assignment ternary

在三元运算符中调用的方法递增变量并返回布尔值.当函数返回false时,将还原该值.我期望变量为1但是变为0.为什么?

public class Main {
    public int a=0;//variable whose value is to be increased in function
    boolean function(){
        a++;
        return false;
    }
    public static void main(String argv[]){
        Main m=new Main();
        m.a+=(m.function()?1:0);
        System.out.println(m.a);//expected output to be 1 but got a 0 !!!!!
    }
}
Run Code Online (Sandbox Code Playgroud)

gle*_*e8e 23

基本上m.a += (m.function() ? 1 : 0)编译成

 int t = m.a; // t=0 (bytecode GETFIELD)
 int r = m.function() ? 1  : 0; // r = 0 (INVOKEVIRTURAL and, IIRC, do a conditional jump)
 int f = t + r; // f = 0 (IADD)
 m.a = f // whatever m.a was before, now it is 0 (PUTFIELD)
Run Code Online (Sandbox Code Playgroud)

以上行为均在JLS 15.26.2(JAVA SE 8版)中指定


Ell*_*sch 19

您有两个操作m.a在一个呼叫中运行; 在main

m.a += (m.function()?1:0);
Run Code Online (Sandbox Code Playgroud)

推送a帧的值,然后调用m.function()(返回false),因此三元扩展为m.a += 0;(并且m.a帧的值被添加0并存储在其中m.a).因此,该值以递增m.function()(然后复位main).以这种方式考虑,

m.a = m.a + (m.function() ? 1 : 0);
Run Code Online (Sandbox Code Playgroud)

m.a在评估之前确定值m.function()(因此它是后增量操作).对于你期望的结果,你可以做到

m.a = (m.function() ? 1 : 0) + m.a;
Run Code Online (Sandbox Code Playgroud)

  • 为什么这样评价?您能引用涵盖此内容的JLS来源吗? (3认同)
  • http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.26.2解释了如何评估复合赋值@JohnKugelman. (3认同)