class Test {
public static void main() {
String s1 = null + null; //shows compile time error
String s1 = null;
String s2 = s1 + null; //runs fine
}
}
有人可以解释一下这种行为的原因吗?
答案 0 :(得分:28)
此代码:
String s1 = null + null;
尝试对两个null
执行加法运算,这是无效的。
在这里:
String s1 = null;
String s2 = s1 + null;
您已将null
分配给s1
。然后,您执行s1
和null
的连接。 s1
的类型为String
,因此null
中的s1 + null
将根据字符串转换规则转换为"null"
字符串,如JLS §15.1.11 - String Conversion:中所示}
如果引用为null,则将其转换为字符串
"null"
(四个 ASCII字符n, u, l, l
)。否则,转换就像通过调用一样执行 没有参数的引用对象的
toString
方法;但如果 调用toString
方法的结果是null
,然后是字符串"null"
而是用来代替。
和连接将以 - s1 + "null";
答案 1 :(得分:15)
+
运算符String
并置仅适用于其中一个(或两个)操作数的类型为String
的情况。
This is defined in the Java Language Specification
如果
+
运算符的任一操作数的类型为String
,则操作为字符串连接。
在
String s1 = null + null; //shows compile time error
操作数具有null
类型,即。不是String
,所以不会发生字符串连接。 Java然后认为你正在做一个也不适用于null
类型的补充。
在
String s2 = s1 + null; //runs fine
s2
的类型为String
,即使它引用null
,也可能会发生字符串连接。
答案 2 :(得分:9)
在下面的情况下,您正在对两个null
执行操作,并且+
没有为null
定义String s1 = null + null;
。
String
在这一部分中,您正在执行null
和String s2 = s1 + null;
的连接。
String abcd = (String) null + null;
另一个有趣的案例是,
String
当您将null
转换为null
时,这将导致“nullnull”字符串,并且将再次执行连接。因此,首先String
将被视为{{1}}。
答案 3 :(得分:3)
来自Javadoc:
Java语言为字符串提供特殊支持 连接运算符(+),以及将其他对象转换为 字符串。字符串连接是通过实现的 StringBuilder(或StringBuffer)类及其
append
方法
因此,至少左操作数不能为空,因为StringBuffer.append(Object object)
接受Object
(包括null
)作为参数。
答案 4 :(得分:2)
基本上这是因为您正在处理文字,因此,COMPILER正在尝试对这些文字值执行操作。它发生在编译时,并且与两个空值无关。
您获得的编译器错误等同于异常 - 编译器不知道如何处理它,因此它会出错并向类型提供说明它不起作用的解释。