Come JLS corrisponde a Sun javac / perché non corrispondono
Domanda
In Java dato questo:
String a = "str";
CharSequence b = "charseq";
è possibile scrivere
b = b + a;
, ma non può scrivere (dà un errore del compilatore)
b += a;
L'errore è
incompatible types
found : java.lang.CharSequence
required: java.lang.String
Ora, in JLS Seconda edizione questo era spiegabile con questa linea in 15.26.2 composte di assegnazione Operatori :
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.
Ma in JLS Terza edizione questo commento è scomparso, l'unica cosa che viene detto su di operatore composto è all'indirizzo 15.26.2 composte di assegnazione Operatori :
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.
che non sembra al lavoro (vedi sopra).
Quindi la mia domanda è - che cosa è esattamente la relazione tra javac e JLS ed è questo particolare esempio un errore nel javac o un errore in JLS
?Soluzione
compiler error is a bug in your version javac. As pointed in prior answer this bug is fixed in Java 7.
See eg Bug ID 7058838 at Sun bug database:
description:
A following function cannot be compiled in java 1.6 or less,. but it can be compiled in java 1.7.
public static void main(String[] args) { Object x = "x"; String y = "y"; x += i; }
- state:
Not a Defect - evaluation:
For an Object x and a String y, x+=y is just x=(Object)(x+y). Since y is a String, x undergoes string conversion to produce a string which is concatenated with y, before the no-op cast to Object. The JLS has not changed in this area between SE 6 and SE 7; the program should have been legal for many years.
For a background, see also old Bug Id 4741726
- description:
javac used to allow expressions of the form
o += s
where o is a variable of type Object and s is an expression of type String. We fixed that recently (4642850) and this caused a build failure (4741702). Perhaps this is common enough that we should relax the spec instead of fixing the compiler? - Category:
java:compiler - Release Fixed:
7(b25) - as far as I understand, this means fixed in build 25 of Java 7 - evaluation:
I'm inclined to relax the spec, though we'd have to know what other implementations do before making a final call on this.
2002-09-04
JLS3 permits Object+=String because the '+' means string concatenation and that is able to concatenate an Object with a String as easily as a String with an Object.
2008-01-31
Altri suggerimenti
should be a javac bug then.
compiles fine in javac 7. so somebody reported it and it's fixed.
In essence, you answered your own question:
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.
Note that you're left-hand operand IS NOT of type String