Оператор «+» не может быть применен к объекту и строке

12

Следующий код:

void someMethod(Object value)
{
    String suffix = getSuffix();
    if (suffix != null)
        value += suffix;

    [...]
}

компилируется без ошибок в JDK 8 (с использованием -source 1.6), но завершается с ошибкой в ​​JDK 6 с сообщением об ошибке:

Operator '+' cannot be applied to java.lang.Object and java.lang.String

Хотя я понимаю, в чем заключается ошибка, почему она компилируется с JDK 8? Это где-нибудь задокументировано?

Grodriguez
источник
Я думаю, значение не обязательно должно быть String. Если значение является целым числом, то нет смысла добавлять к нему строку. Возможно, вы можете попытаться преобразовать значение в строку
fedoraHacker
2
@fedoraHacker Выражение value = value + suffixполностью допустимо, независимо от типа значения. Так что, мне кажется, value += suffixэто тоже должно быть законно.
Гродригес
вау, я понятия не имел Я думал, что вся суть разных объектов заключается в том, чтобы определить правила для того, что данные могут и не могут делать. Весь смысл наличия разных типов данных и объектов состоит в том, чтобы разделить ответственность, чтобы убедиться, что типы делают одно, а делают это хорошо. Я просто сбит с толку, что вы можете так смешивать типы данных. Что ж, ты учишься чему-то каждый день :) и значение = значение + суффикс - это то же самое, что значение + = суффикс, так что я вообще не оспариваю синтаксис
fedoraHacker
1
Да, но тип String несколько особенный. Оператор + здесь является «оператором конкатенации строк»; если только один из операндов является строкой, другой преобразуется в строку перед вычислением выражения. Смотрите этот раздел JLS .
Гродригес
Ах, я вижу, не знал, что строка преобразует это так. Спасибо, что нашли время ответить даже после того, как на вопрос был дан ответ!
fedoraHacker

Ответы:

16

JLS 15.26.2. Сложные Операторы Назначения заявляют :

Выражение присваивания соединения формы E1 op= E2эквивалентно E1 = (T) ((E1) op (E2)), где Tэто тип E1, за исключением того, что E1вычисляется только один раз.

Это предложение то же самое от Java 6 до Java 14 , и, вероятно, никогда не менялось с самого начала Java.

Так value += suffixже, какvalue = (Object) (value + suffix)

Компилятор Java 6 не должен был скомпилировать этот оператор.

Andreas
источник
2
JDK (javac) ошибка тогда. Спасибо за указатель на JLS, я как-то пропустил это.
Гродригес
3
15.18.1. Оператор конкатенации строк также имеет отношение к объяснению того, почему эквивалентный оператор value = (Object) (value + suffix)должен компилироваться.
Dukeling