开发者

How JLS corresponds to Sun javac / why they do not match

In Java given this:

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

you can write

b = b + a;

but cannot write (gives a compiler error)

b += a;

The error is

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

Now in JLS Second Edition this was explainable by this line in 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.

But in JLS Third Edition this comment disappeared, the only thing that is said about compound operator is at 15.26.2 Compound Assignment Operators:

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.

which doesn't seem to work (see above).

So my question is - what exactly is the relationship between javac and JLS and is this particular example an error in javac or an error in JLS?


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


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜