Почему + работает со строками в Java? - PullRequest
7 голосов
/ 28 марта 2011

Java не может перегружать операторы, но + работает нормально для String и Integer и некоторых других классов. Как это возможно?

Обновление:
Почему это работает?

Integer i = 4;
Integer p = 5;

System.out.println(i*p); // prints 20

Ответы [ 6 ]

7 голосов
/ 28 марта 2011

+ не является примером перегрузки оператора. + встроен в язык как оператор конкатенации и оператор арифметического сложения.

Это означает, что человек, пишущий программу на Java, не может перегружать операторы, но в отношении грамматики языка Java + определяется как оператор объединения и сложения.

EDIT

Работает для других классов, таких как Integer и Double из-за autoboxing .

Если вы посмотрите на байт-код программы Java, которая выполняет конкатенацию строк, вы увидите, что она создает StringBuilder и использует метод append(). Компилятор Java видит оператор + и понимает, что операнды являются строками, а не примитивными типами (например, int).

Если вы посмотрите на байт-код программы, которая выполняет сложение целых чисел, вы увидите, что она использует инструкцию iadd для выполнения сложения целых чисел. Это потому, что компилятор понимает, что операнды операции + являются целыми числами.

Если сделать что-то вроде Integer i = 4, то байт-код покажет, что вы на самом деле делаете Integer i = Integer.valueOf(4). Это называется автобоксом. Позже, когда вы сделаете что-то вроде i + p, где оба i и p имеют тип Integer, сгенерированный байт-код покажет, что вы делаете i.intValue() + p.intValue(), где возвращаемые типы обоих методов int (действительная инструкция для байт-кода снова равна iadd).

Вот почему + работает Integer, хотя они не являются настоящими примитивными типами.

6 голосов
/ 28 марта 2011

Это работает для примитивных оболочек, таких как Integer, из-за autoboxing .

Это работает для String, потому что это особый случай для объединения строк :

Язык Java обеспечивает специальную поддержку оператора конкатенации строк (+) и преобразования других объектов в строки. Конкатенация строк реализуется с помощью класса StringBuilder (или StringBuffer) и его метода добавления. Строковые преобразования реализуются через метод toString, определяемый Object и наследуемый всеми классами в Java. Для получения дополнительной информации о конкатенации и преобразовании строк см. Гослинг, Джой и Стил, Спецификация языка Java.

5 голосов
/ 28 марта 2011

+ является встроенной операцией.Это исключение, а не правило.

2 голосов
/ 29 марта 2011

Язык Java обеспечивает специальную поддержку оператора конкатенации строк (+) и преобразования других объектов в строки.

String s = "string 1" + "string 2";

На самом деле выполняется

(new StringBuilder()).append("string 1").append("string 2").toString()
2 голосов
/ 28 марта 2011

Java не допускает перегрузку пользовательского оператора, но разработчик компилятора может все еще сказать компилятору, что String1 + String2 == String1String2, и заменить соответствующий вызов метода конкатенации на оператор +.

1 голос
/ 29 марта 2011

Как сказал @yan, это исключение, а не правило. Строки имеют особый статус в Java. Есть целый подраздел Спецификации языка Java, посвященный + в его роли оператора конкатенации строк: §15.18.1 .

Что касается вашего обновления, это еще один особый случай. Java иногда , в зависимости от случая, достаточно умен, чтобы преобразовывать вещи, которые не String с в String с, когда требуется String с. Один из этих особых случаев - тот, который вы описали, когда примитивы появляются в месте, где требуется String. Примитивы сначала преобразуются в свои ссылочные типы - Integer, Double и т. Д. - а затем в String с помощью метода toString().

Другой особый случай - это когда один String и один не String объединяются с оператором объединения строк +, как описано в JLS §5.4 - Преобразование строк .

Для полноты: + в его более общей роли «сложения чисел» описывается в другой части §15.18, §15.18.2 - Аддитивные операторы (+ и -) для числовых типов .

...