4

在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 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.

这似乎不起作用(见上文)。

所以我的问题是 - javac 和 JLS 之间究竟是什么关系,这个特定示例是 javac 中的错误还是 JLS 中的错误?

4

3 回答 3

4

编译器错误是您的 javac 版本中的错误。正如前面的回答所指出的,这个错误在 Java 7 中得到了修复。

参见例如Sun 错误数据库中的 错误 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 是一个字符串,因此在无操作转换为 Object 之前,x 会进行字符串转换以生成与 y 连接的字符串。在 SE 6 和 SE 7 之间,JLS 在这方面没有变化;该计划应该合法多年。


有关背景,另请参阅旧错误 ID 4741726

  • 描述:

    javac 用于允许以下形式的表达式,o += s其中 o 是 Object 类型的变量,s 是 String 类型的表达式。我们最近修复了该问题 (4642850),这导致构建失败 (4741702)。也许这很常见,我们应该放宽规范而不是修复编译器?

  • 类别:
    java:编译器
  • Release Fixed:
    7(b25) - 据我了解,这意味着在 Java 7 的 build 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.

请注意,您是左操作数 IS NOT 类型为 String

于 2011-09-06T13:24:09.440 回答