Java中,null对象可以被打印出来,也可以用来与另一个对象比较。下面是示例代码:
package testnullpointerexception;
public class Person {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [name=" + name + "]";
}
}
package testnullpointerexception;
public class TestNullPointerException {
public static void main(String[] args) {
// TODO Auto-generated method stub
/**
* 当一个对象是null时,我们可以将它打印出来,
* 也可以把它拿来做比较,但是
* 不能对它应用.运算符。
*/
Person person = null;
System.out.println(person);
System.out.println(isNull(person));
}
public static boolean isNull(Object o) {
if(o == null) {
return true;
}
return false;
}
}
运行程序,打印出:
null
true
但是,不能对一个null对象应用.(点运算符)。如果对一个null对象应用点运算符,就会报java.lang.NullPointerException(空指针异常)。示例代码如下:
到最后,还有一个问题,当用System.out.println()打印一个对象时,不是要调用对象的toString()方法吗?但是打印时并没有报错,这什么原因呢?
查看println()源码:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
方法首先把对象转化为字符串,查看valueOf()源码:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
可以看到,把对象转化为字符串的过程是,先把对象和null比较,如果为真,直接返回“null”,如果为假,也就是说对象不是null,再调用toString方法。这就是打印null对象不报错的原因。
我们顺便看看print()的源码:
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
可见,print()只是用来打印字符串对象的,而且针对null字符串也有特别处理。
总结:本文的目标是理清null,让自己远离空指针异常。关于空指针异常,我刚刚想到一个比喻:我声称自己可以给你钱,给你房,给你车;你信了,你就来向我要,结果发现我没有。这个过程产生空指针异常的过程一样。(这个比喻还可以延伸往好的一面,比如Set<String> set = new HashSet<String>(),有点儿像:我声称自己可以给你钱,给你房,给你车。其实,我还可以给土地,但是我没有告诉。于是,你只会向我要钱,房和车,而不会向我要土地。set指向的地方,不仅包括Set有的,其实还包括一些Set没有的。)