背景
我想了解为什么一段代码不会引发 NullPointerException。
源代码
考虑以下代码:
public class Agent {
public List files = new ArrayList();
public void deliver() {
if( files != null && files.iterator().hasNext() ) {
File file = (File)files.iterator().next();
}
files = new ArrayList();
}
}
该deliver
方法被重复调用,而以下代码在单独的线程中运行:
public void run() {
agent.files = null;
}
只有一个agent
实例。
问题
永远不会抛出 NullPointerException。
但是,当deliver
方法暂停时,即使是 0 毫秒,也会按预期抛出 NullPointerException:
public void deliver() {
if( files != null ) {
Thread.currentThread().sleep( 0 );
if( files.iterator().hasNext() ) {
File file = (File)files.iterator().next();
}
}
files = new ArrayList();
}
我的理解是,理论上,检查files == null
和调用之间存在竞争条件files.iterator().hasNext()
。在实践中,如果不引入暂停(即,将空检查与后续方法调用分开),我就无法触发竞争条件。
问题
为什么deliver
null检查和用法结合在同一个语句中,第一种方法不抛出异常?