Конкатенация строк и персонажей
Следующие утверждения,
String string = "string";
string = string +((char)65) + 5;
System.out.println(string);
Произвести вывод stringA5
.
Далее,
String string = "string";
string += ((char)65) + 5;
System.out.println(string);
Произведите string70
.
Где разница?
Ответы
Ответ 1
Вы видите это поведение в результате комбинации приоритетов операторов и преобразования строк.
JLS 15.18.1 утверждает:
Если только одно выражение операнда имеет тип String, тогда преобразование строки (§5.1.11) выполняется в другом операнде для создания строки во время выполнения.
Поэтому правые операнды в вашем первом выражении неявно преобразуются в строку: string = string + ((char)65) + 5;
Для второго выражения, однако string += ((char)65) + 5;
, должен быть рассмотрен оператор присваивания +=
вместе с +
. Так как +=
слабее, чем +
, сначала вычисляется оператор +
. Там мы имеем char
и int, что приводит к двоичной числовой рекламе до int
. Только тогда +=
оценивается, но в это время результат выражения, включающего оператор +
, уже был оценен.
Ответ 2
Случай 1
string = string +((char)65) + 5;
все рассматривается как String, но во втором случае
Последовательность выполняемой операции:
-
string +((char)65 = stringA
-
stringA + 5 = stringA5
Случай 2
string += ((char)65) + 5;
первая правая сторона вычисляется означает, что первая операция будет выглядеть как ((char)65) + 5
, поэтому результат ((char)65) + 5 is 70
и после этого + = операция.
Последовательность выполняемой операции:
-
(char)65 + 5 = 70
-
string + 70 = string70
Давайте посмотрим еще один пример
String string = "string";
string += ((char)65) + 5 + "A";
System.out.println(string);
Выход string70A
Причина
Вычисляется одна и та же первая правая часть и выполняется секвенция выполняемой операции
-
(char)65 + 5 = 70
-
70 + "A" = 70A
-
string + 70A = string70A
Ответ 3
Когда вы пишете:
string = string + ((char)65) + 5;
Это похоже на запись:
String string =
new StringBuilder(string).append((char)65).append((int)5).toString();
Это похоже на добавление string
в A
(представление char десятичного знака 65) и 5
.
В последнем вы сначала вычисляете правую руку, а затем добавляете результат в string
, это как запись:
string = string + 70;
Ответ 4
string = string +((char)65) + 5;
Это означает "Установить строку в конкатенацию string
, ((char)65)
и 5
." Это оценивается слева направо (сначала string + ((char)65)
, затем +5
, и конкатенация строки и целого числа преобразует это целое число в строку.
string += ((char)65) + 5;
Это означает "Вычислить результат ((char)65)+5
и добавить его в строку" - вся правая часть оценивается перед добавлением результата в строку. Так как a char
на самом деле всего лишь 16-битное целое число, оно объединяет их как целые числа, давая 70, а затем добавляет это к string
.
Ответ 5
Это тот же случай, что и пример:
System.out.println("abc"+10 + 5);
создает abc105 (добавить как String)
и
System.out.println(5 + 10);
выводит 15 (добавить как число)
String
, включенный в операцию (первое место), заставляет все элементы обрабатываться как Strings
во время выполнения операции. В вашем случае с +=
однако операция выполняется сначала в правой части (обрабатывая элементы как int
) из-за приоритета оператора, а затем объединяется с String
.