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