JAVA中的null问题
在学习ADT设计的时候,老师提到过尽量避免方法返回值为null的情况,否则很可能导致无效指针引用而抛出异常。但是在实际应用的时候,经常会出现如下的情况:
我们设计一个梯子类及一个猴子类,梯子含有一个猴子的属性,梯子上可能有猴子,也可能没有,因此是可变的。
class Ladder {
private Monkey monkey; //梯子上的猴子
/*设置猴子*/
public void setMonkey(Monkey monkey) {
this.monkey = monkey;
}
/*获取猴子*/
public Monkey getMonkey() {
return monkey;
}
}
class Monkey {
private final String name;//猴子的名字
public Monkey(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
我们在创建一个新的梯子对象的时候,猴子属性是指向null的,而我们无法保证setMonkey()方法一定在getMonkey()方法之前调用,并且也可能出现setMonkey(null)的情况,因此在程序执行以下语句的时候,会抛出NullPointerException异常
public static void main(String[] args) {
Ladder ladder = new Ladder();
System.out.println("梯子上的猴子:"+ladder.getMonkey().getName());
}
这个时候我们怎么办呢?只能在每次调用前判断是否为空指针,这样会显得很繁琐,而且会导致程序到处都是危险的空指针,指不定哪儿就会突然爆炸。经过查阅资料,可以使用如下的方法:
class Ladder {
private Monkey monkey;
public void setMonkey(Monkey monkey) {
this.monkey = monkey;
}
public Monkey getMonkey() {
if(monkey == null) {
return Monkey.NullMonkey;//用空对象代替空指针
}
return monkey;
}
}
class Monkey {
private final String name;
public static final Monkey NullMonkey = new Monkey("不存在这个猴子");//代替空猴子引用
public Monkey(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
这样在执行System.out.println(“梯子上的猴子:”+ladder.getMonkey().getName());就不会报错,这样转而输出的是"梯子上的猴子:不存在这个猴子"。
这是一种新的用空对象代替空指针的思路,有效避免了程序到处是空指针,或者进行繁琐判断的情况,在一些场景可能会很好用,但是也存在其他的缺点,就是虽然没有编译错误了,但是增加了逻辑错误的可能。