为何"abc" + null 结果abcnull
String s1 = "abc";
String s2 = null;
String s3 = s1+ s2;
System.out.println(s3);
Run Code Online (Sandbox Code Playgroud)
结果: abcnull
因为Java将创建一个StringBuilder的追加s1,或"abc",对s2或null.
根据StringBuilder.append(String)的规范 -
If str is null, then the four characters "null" are appended
Run Code Online (Sandbox Code Playgroud)
所以它变成了相同的 "abc" + "null"
我们来看看你的代码示例(我把它放在一个方法中):
public static void main(String[] args)
{
String s1 = "abc";
String s2 = null;
String s3 = s1+ s2;
System.out.println(s3);
}
Run Code Online (Sandbox Code Playgroud)
如果我们采用字节码(通过调用javap -c得到):
public static void main(java.lang.String[]);
Code:
0: ldc #2; //String abc
2: astore_1
3: aconst_null
4: astore_2
5: new #3; //class java/lang/StringBuilder
8: dup
9: invokespecial #4; //Method java/lang/StringBuilder."<init>":()V
12: aload_1
13: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
16: aload_2
17: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
20: invokevirtual #6; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
23: astore_3
24: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream;
27: aload_3
28: invokevirtual #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
31: return
Run Code Online (Sandbox Code Playgroud)
Java创建一个StringBuilder并附加Strings 的值s1和s2.
所以你必须要小心,如果你期望NullPointerException,因为Java中的连接将绕过这个问题.
旁注:正如Jon Skeet所指出的,这最终只是实现细节 - 它是Java规范,它保证null在转换为String时变为"null".但是,这个字节码至少可以显示幕后实际发生的情况.