Странное поведение Java += оператор
Кто-нибудь может мне это объяснить,
String str = "Hello";
str += ((char)97) +2; // str = "Hello99";
str = str +((char)97)+2; // str = "Helloa2";
делает +=
Оператор сначала оценивает правую сторону, а затем соединяет ее с левой стороной?
5 ответов
Разница связана с порядком операций. Следующие:
str += ((char)97) +2;
эквивалентно:
str = str + (((char)97) + 2);
С другой стороны, следующее:
str = str +((char)97)+2;
эквивалентно:
str = (str + ((char)97)) + 2;
Обратите внимание на разницу в расположении скобок.
Теперь давайте рассмотрим два случая:
1) str = str + (((char)97) + 2)
:
Вот, 97 + 2
оценивается первым. Результатом является int
(99
), который преобразуется в строку и добавляется к str
, Результат "Hello99"
,
2) str = (str + ((char)97)) + 2
:
Вот, (char)97
('a'
) добавляется к строке, а затем 2
преобразуется в строку и добавляется к результату. Это дает "Helloa2"
,
Да. Соответствующий раздел JLS находится здесь: http://java.sun.com/docs/books/jls/first_edition/html/15.doc.html
Во время выполнения выражение оценивается одним из двух способов. Если выражение левого операнда не является выражением доступа к массиву, то необходимо выполнить четыре шага:
- Во-первых, левый операнд вычисляется для создания переменной. Если эта оценка завершается преждевременно, то выражение присваивания завершается преждевременно по той же причине; правый операнд не оценивается и присваивания не происходит.
- В противном случае значение левого операнда сохраняется, а затем вычисляется правый операнд. Если эта оценка завершается преждевременно, то выражение присваивания завершается преждевременно по той же причине, и назначение не происходит.
- В противном случае сохраненное значение левой переменной и значение правого операнда используются для выполнения двоичной операции, указанной оператором сложного присваивания. Если эта операция завершается внезапно (единственная возможность - целочисленное деление на ноль - см. §15.16.2), то выражение присваивания завершается внезапно по той же причине, и присвоение не происходит.
- В противном случае результат двоичной операции преобразуется в тип левой переменной, а результат преобразования сохраняется в переменной.
(Акцент мной.)
Это все об ассоциативности операторов.
str += ((char)97) +2;
Будет переводить на:
str = str + ( ((char)97)+2 );
Ваша первая строка эквивалентна:
str = str + ((char)97) + 2);
а ваш второй эквивалентен:
str = (str + ((char)97)) + 2
str = str +((char)97)+2
потому что first is string Оператор '+' используется в качестве строки concat (другие значения преобразуются в строку)
str +=((char)97)+2
первая правая часть оценивается как 99 (двухбайтовая сумма), чем str + 99 -> string concat