Поясните код Java?

Есть следующий код:
int a = 1, b = 2;
b=a + 0*(a=b);
System.out.println(b+" " +a);

В результате значения a и b меняются местами. Не могу понять в какой момент это происходит и почему a и b не становятся равными друг другу?
  • Вопрос задан
  • 532 просмотра
Решения вопроса 2
xez
@xez Куратор тега Java
TL Junior Roo
Вот что происходит после компиляции:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

public class test {
    public test() {
    }

    public static void main(String[] args) {
        byte a = 1;
        byte b = 2;
        byte var10000 = a;
        a = b;
        int b1 = var10000 + 0 * b;
        System.out.println(b1 + " " + a);
    }
}


Как можно заметить, никакой магии здесь нет.

В общем и целом я не рекомендую использовать такую "магию". Гораздо лучше писать понятный и очевидный код.
Ответ написан
Комментировать
@bromzh
Drugs-driven development
Сперва вычисляется выражение справа от присваивания, потом оно записывается в переменную, указанную слева. При этом, так как эти переменные - числа, то они неизменяемы. Т.е. сами значения таких переменных изменить нельзя, можно лишь присвоить им новые. Вычисление выражений использует старое значение идентификатора. Новое значение присвоится только после всех вычислений.
Тут сначала вычислится выражение b (оно будет равно первоначальному значению b, т.е. 2) и его значение сохранится в переменной a (которая вторая по-счёту). Но так как это тоже часть выражения, то в первой a будет ещё старое значение. Оно складывается с результатом выражения 0*(a=b), получается снова старое значение a, которое и присвоится идентификатору b.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@aol-nnov
надо полагать, это пример undefined behaviour.

страшная магия, которая, будучи примененной в продакшене, испортит здоровый сон разработчику.
компилятор джавы, как показано в одном из ответов, добавил временную переменную, чем и обеспечил такое поведение.
Например, если изобразить этот пример на си (gcc), там такой магии не будет. Опять же, полагаю, другой компилятор может поступить иначе.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы