简体   繁体   中英

Why doesn't System.out.println() throw NullPointerException?

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 ?

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 :)

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();
}

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".

Null is special cased inside the print function:

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

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.

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);
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM