为什么"abc"+ null结果为abcnull

ban*_*ara 1 java null

为何"abc" + null 结果abcnull

String s1 = "abc";
String s2 = null; 
String s3 = s1+ s2;

System.out.println(s3);
Run Code Online (Sandbox Code Playgroud)

结果: abcnull

Zac*_*h L 7

因为Java将创建一个StringBuilder的追加s1,或"abc",s2null.

根据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 的值s1s2.

所以你必须要小心,如果你期望NullPointerException,因为Java中的连接将绕过这个问题.

旁注:正如Jon Skeet所指出的,这最终只是实现细节 - 它是Java规范,它保证null在转换为String时变为"null".但是,这个字节码至少可以显示幕后实际发生的情况.