Как JLS соответствует Sun javac / почему они не совпадают

StackOverflow https://stackoverflow.com/questions/7320546

  •  27-10-2019
  •  | 
  •  

Вопрос

В 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top