在Java中给出以下内容:
String a = "str";
CharSequence b = "charseq";
Run Code Online (Sandbox Code Playgroud)
你可以写
b = b + a;
Run Code Online (Sandbox Code Playgroud)
但无法编写(产生编译器错误)
b += a;
Run Code Online (Sandbox Code Playgroud)
错误是
incompatible types
found : java.lang.CharSequence
required: java.lang.String
Run Code Online (Sandbox Code Playgroud)
现在在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复合赋值运算符:
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中修复。
请参见例如Sun Bug数据库中的Bug ID 7058838:
描述:
以下函数不能在Java 1.6或更低版本中编译。但可以在Java 1.7中进行编译。
public static void main(String[] args) {
Object x = "x";
String y = "y";
x += i;
}
Run Code Online (Sandbox Code Playgroud)对于对象x和字符串y,x + = y只是x =(Object)(x + y)。由于y是字符串,因此x在无操作强制转换为Object之前,将进行字符串转换以生成与y串联的字符串。JLS在SE 6和SE 7之间的该区域中未更改;该程序应该已经合法多年了。
有关背景,另请参见旧的Bug ID 4741726
javac用于允许以下形式的表达式,
o += s其中o是Object类型的变量,而s是String类型的表达式。我们最近修复了此问题(4642850),这导致构建失败(4741702)。也许这很常见,我们应该放松规范而不是修复编译器?
我倾向于放宽规范,尽管在最终确定之前我们必须了解其他实现方式。
2002-09-04
JLS3允许使用Object + = String,因为'+'表示字符串连接,并且能够像使用带对象的字符串一样容易地将带对象的对象连接起来。
2008-01-31