4

これを与えられたJavaでは:

String a = "str";
CharSequence b = "charseq";

あなたは書ける

b = b + a;

書き込みはできません (コンパイラ エラーが発生します)。

b += a;

エラーは

incompatible types
found   : java.lang.CharSequence
required: java.lang.String

現在、JLS Second Edition では、これは15.26.2 Compound Assignment Operatorsの次の行で説明できました。

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 第 3 版では、このコメントは消えました。複合演算子について述べられていることは、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 のエラーですか?

4

3 に答える 3

4

コンパイラ エラーは、バージョン javac のバグです。前の回答で指摘したように、このバグは Java 7 で修正されています。

たとえば、Sun バグ データベースの Bug ID 7058838を参照してください。

  • 説明:

    次の関数は、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 と連結されてから、オブジェクトへの no-op キャストが行われます。JLS は、SE 6 と SE 7 の間でこの領域で変更されていません。プログラムは何年もの間合法であったはずです。


背景については、古いバグ ID 4741726も参照してください。

  • 説明:

    javaco += sは、o が Object 型の変数で、s が String 型の式である形式の式を許可していました。私たちは最近これを修正し (4642850)、これが原因でビルドが失敗しました (4741702)。おそらくこれは、コンパイラを修正する代わりに仕様を緩和するのに十分なほど一般的ですか?

  • カテゴリ:
    java:コンパイラ
  • リリース修正済み:
    7(b25) - 私の知る限り、これは Java 7 のビルド 25 で修正されたことを意味します
  • 評価:

    私は仕様を緩和する傾向にありますが、これについて最終的な決定を下す前に、他の実装が何をするかを知る必要があります。
    2002-09-04
    JLS3 は Object+=String を許可します。'+' は文字列の連結を意味し、文字列とオブジェクトを連結するのと同じくらい簡単にオブジェクトと文字列を連結できるからです。
    2008-01-31

于 2011-09-07T06:34:46.427 に答える
2

その場合、javac のバグである必要があります。

javac 7 で正常にコンパイルされるため、誰かが報告し、修正されました。

于 2011-09-06T20:20:51.640 に答える
0

本質的に、あなたはあなた自身の質問に答えました:

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.

左側のオペランドは文字列型ではないことに注意してください

于 2011-09-06T13:24:09.440 に答える