Как JLS соответствует Sun javac / почему они не совпадают
Вопрос
В Java, учитывая это:
String a = "str";
CharSequence b = "charseq";
вы можете написать
b = b + a;
но не может записать (выдает ошибку компилятора)
b += a;
Ошибка заключается в
incompatible types
found : java.lang.CharSequence
required: java.lang.String
Теперь, во Втором издании JLS, это было объяснено этой строкой в 15.26.2 Составные операторы присваивания:
All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.
Но в третьем издании JLS этот комментарий исчез, единственное, что говорится о составном операторе, - это at 15.26.2 Составные операторы присваивания:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
который, похоже, не работает (см. Выше).
Итак, мой вопрос заключается в следующем: какова именно связь между javac и JLS и является ли этот конкретный пример ошибкой в javac или ошибкой в JLS?
Решение
ошибка компилятора это ошибка в вашей версии javac.Как указано в предыдущем ответе эта ошибка исправлена в Java 7.
Смотрите , например Идентификатор ошибки 7058838 в базе данных ошибок Sun:
Описание:
Следующая функция не может быть скомпилирована на Java 1.6 или менее поздней версии,.но он может быть скомпилирован на java 1.7.
public static void main(String[] args) { Object x = "x"; String y = "y"; x += i; }
- состояние:
Это не Дефект - оценка:
Для объекта x и строки y x+=y - это просто x=(Object)(x+y).Поскольку y является строкой, x подвергается строковому преобразованию для получения строки, которая объединяется с y, перед безоперационным преобразованием в Object .JLS не изменился в этой области между SE 6 и SE 7;программа должна была быть легальной в течение многих лет.
Справочную информацию см. также в разделе Старые Идентификатор ошибки 4741726
- Описание:
javac используется для разрешения выражений вида
o += s
где o - переменная типа Object, а s - выражение типа String.Недавно мы исправили это (4642850), и это вызвало сбой сборки (4741702).Возможно, это достаточно распространенное явление, чтобы нам следовало смягчить спецификацию вместо исправления компилятора? - Категория:
java:компилятор - Исправлен выпуск:
7 (b25) - насколько я понимаю, это означает исправлено в сборке 25 Java 7 - оценка:
Я склонен смягчить спецификацию, хотя мы должны были бы знать, что делают другие реализации, прежде чем делать окончательный вызов по этому вопросу.
2002-09-04
JLS3 разрешает Object+=String, потому что '+' означает конкатенацию строк, и это позволяет объединить объект со строкой так же легко, как строку с объектом.
2008-01-31
Другие советы
тогда это должна быть ошибка javac.
отлично компилируется в javac 7.итак, кто-то сообщил об этом, и это исправлено.
По сути, вы сами ответили на свой вопрос:
All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the left-hand operand is of type String.
Обратите внимание, что ваш левый операнд НЕ имеет типа String