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第2版では、これはこの行で説明可能でした 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第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のエラーですか?

役に立ちましたか?

解決

コンパイラエラー あなたのバージョンJavacのバグです。として 事前の回答を指し示しています このバグはJava 7で固定されています。

例を参照してください バグ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と連結された文字列を生成します。 JLSは、SE 6からSE 7の間にこの領域では変更されていません。このプログラムは長年合法であったはずです。


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

  • 説明:

    Javacはフォームの表現を許可していました o += s ここで、oはタイプオブジェクトの変数であり、sは型文字列の式です。最近(4642850)を修正しましたが、これによりビルド障害が発生しました(4741702)。おそらく、これはコンパイラを修正する代わりにスペックをリラックスさせる必要があるほど十分に一般的ですか?

  • カテゴリー:
    Java:コンパイラ
  • 修正されたリリース:
    7(B25) - 私が理解している限り、これはJava 7のビルド25で固定されていることを意味します
  • 評価:

    私はスペックをリラックスする傾向がありますが、これを最終的に呼び出す前に他の実装が何をするかを知る必要があります。
    2002-09-04
    jls3はオブジェクトを許可します+=文字列「+」は文字列の連結を意味し、オブジェクトをストリングを持つ文字列で簡単に連結することができるためです。
    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.

あなたが左手のオペランドはタイプの文字列ではないことに注意してください

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top