Как JLS соответствует Sun Javac / почему они не совпадают - PullRequest
4 голосов
/ 06 сентября 2011

На 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 этот комментарий исчез, единственное, что сказано о составном операторе, это 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?

Ответы [ 3 ]

4 голосов
/ 07 сентября 2011

ошибка компилятора - это ошибка в вашей версии 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 = (объект) (x + y). Так как y является строкой, x подвергается преобразованию строки для получения строки, которая соединяется с y, перед тем как объект не будет приведен к типу no-op. 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

2 голосов
/ 07 сентября 2011

должно быть ошибкой javac.

прекрасно компилируется в javac 7. поэтому кто-то сообщил об этом, и это исправлено.

0 голосов
/ 06 сентября 2011

По сути, вы ответили на свой вопрос:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...