Why doesn't System.out.println() throw NullPoi

2019-02-17 10:03发布

问题:

This might be a very basic question, but I still don't know the answer.

String abc = null;    
System.out.println(abc);

Why does System.out.println print "null" and does not throw NullPointerException?

回答1:

Because it eventually reaches the print method, which prints "null" for a null String :

public void println(String x) {
    synchronized (lock) {
        print(x);
        println();
    }
}

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

The same behavior exists for printing of any null reference (in this case the "null" String is returned by String.valueOf(null) :

public void println(Object x) {
    String s = String.valueOf(x);
    synchronized (lock) {
        print(s);
        println();
    }
}

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}


回答2:

It's behaving as it's documented to. PrintStream.println(String) is documented as:

Prints a String and then terminate the line. This method behaves as though it invokes print(String) and then println().

PrintStream.print(String) is documented as:

Prints a string. If the argument is null then the string "null" is printed. Otherwise, the string's characters are converted into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.

When in doubt, read the documentation :)



回答3:

You can just have a look at PrintStream source code:

public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

public void print(String s) {
    if (s == null) {
        s = "null";
    }
    write(s);
}

As you can see, the null case is handled by just printing "null".



回答4:

Null is special cased inside the print function:

public void print(String s) {
  if (s == null) {
    s = "null";
  }
  write(s);
}


回答5:

According to PrintStream#println()

Prints an Object and then terminate the line. This method calls at first String.valueOf(x) to get the printed object's string value, then behaves as though it invokes print(String) and then println().

According to String#valueOf

Returns the string representation of the Object argument. If the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.



回答6:

System.out.print function source code. If print string is null ,it sets to "null"

public void print(String s) {
if (s == null) {
    s = "null";
}
write(s);
}


回答7:

Well in some circumstances, System.out.println could throw a NullPointerException making you think that is how it works.

If you have a complex object where you have created your own toString() method, there is a potential for the error to occur within that method. You could either accidentally or purposely code that such that the NPE does occur. The object itself is not null, however some of the attributes inside might be null.

Such coding should most likely be discouraged though because it does break the contract as others have pointed out. The desired behavior is to represent a null object as null and not NPE being thrown.