Подтвердить что ты не робот

Увеличение функции, перезаписанное + =

Метод, вызываемый в тройном операторе, приращает переменную и возвращает логическое значение. Когда функция возвращает 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 !!!!!
    }
}
4b9b3361

Ответ 1

В основном 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)

Все описанное поведение указано в JLS 15.26.2 (выпуск JAVA SE 8)

Ответ 2

У вас есть две операции, работающие на m.a за один вызов; в main

m.a += (m.function()?1:0);

подталкивает значение a в кадре, а затем вызывает m.function() (который возвращает false), поэтому троянец расширяется до m.a += 0; (и значение m.a из фрейма добавляется к 0 и сохранен в m.a). Таким образом, значение увеличивается в m.function() (а затем reset в main). Рассмотрим это так,

m.a = m.a + (m.function() ? 1 : 0);

Значение m.a определяется перед оценкой m.function() (таким образом, это операция приращения по почте). Для ожидаемого результата вы могли бы сделать

m.a = (m.function() ? 1 : 0) + m.a;