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
?
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
?
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();
}
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 thenprintln()
.
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 thewrite(int)
method.
When in doubt, read the documentation :)
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.