В Java, почему присваивание в скобках не происходит до того, как вычисляется остальная часть выражения?



Рассмотрим



int a = 20;
a = a + (a = 5); // a == 25, why not 10?


Разве скобки не превосходят все правила приоритета? Являются ли некоторые переменные на RHS предварительно заполненными до оценки определенных выражений?

496   3  

3 ответов:

Потому что a загружается первым в вашем примере, а затем вычисляется бит в скобках. Если вы поменяли порядок:

int a = 20;
a = (a = 5) + a;
System.out.println(a);
10

... вы действительно получаете 10. Выражения вычисляются слева направо.

Рассмотрим это:

f() + g()

f будет вызван раньше g. Представьте себе, насколько это было бы неинтуитивно, в

f() + (g())

Иметь g быть вызванным до f.

Все это подробно описано в JLS §15.7.1 (спасибо @paisanco за то, что поднял его в комментариях).

Из JLS

Язык программирования Java гарантирует, что операнды операторы, по-видимому, оцениваются в определенном порядке оценки, а именно, слева направо.

И

Левый операнд двоичного оператора представляется полностью вычисляется перед вычислением любой части правого операнда.

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

Сгенерированный байт-код:

BIPUSH 20
ISTORE 1
ILOAD 1
ICONST_5
DUP
ISTORE 1
IADD
ISTORE 1
RETURN
LOCALVARIABLE a I

Сначала вы присваиваете 20 первой переменной (a):

BIPUSH 20
ISTORE 1

Затем вы загружаете содержимое первой переменной в стек (20 помещается в стек):

ILOAD 1

Затем вы дважды нажимаете константу '5' в стек (20 5 5):

ICONST_5
DUP

Затем вы сохраняете верхнюю часть стека в первую переменную (a):

ISTORE 1

А теперь 5, стек теперь (20 5). Мы добавляем оба операнда и помещаем их сумму в первую переменную (a):

IADD
ISTORE 1

В качестве следовательно, а теперь 20 + 5 = 25. Мы заканчиваем:

RETURN

Comments

    Ничего не найдено.