[英]Why does this code sometimes throw a NullPointerException?
請考慮以下Java源代碼:
if( agents != null ) {
for( Iterator iter = agents.keySet().iterator(); iter.hasNext(); ) {
// Code that uses iter.next() ...
//
}
}
agents
是HashMap
。
為什么for
語句有時會拋出NullPointerException
?
謝謝。
線程安全
如果您的代碼是多線程的,那么它是可能的。 例如:
public class C {
private Hashtable agents = new Hashtable();
public iterate() {
if( agents != null ) {
for (Iterator iter = agents.keySet().iterator(); iter.hasNext();) {
// Code goes here
}
}
}
如果另一個線程在if
語句執行后(但在for
循環之前)立即將agents
設置為null
,那么您將獲得NullPointerException
。 通過使用訪問器(結合延遲初始化)避免這種情況。
此外,正如其他人所提到的,如果可能的話,避免這種循環結構有利於泛型。 請參閱其他答案了解詳情
配件提供保護
如果您始終使用以下模式,則源代碼中永遠不會出現NullPointerException
(另一方面,第三方代碼可能存在導致代碼失敗的問題,間接失敗,這是不容易避免的)。
public class C {
private Hashtable agents;
private synchronized Hashtable getAgents() {
if( this.agents == null ) {
this.agents = new Hashtable();
}
return this.agents;
}
public iterate() {
Hashtable agents = getAgents();
for (Iterator iter = agents.keySet().iterator(); iter.hasNext();) {
// Code goes here
}
}
}
迭代代理的代碼不再需要檢查null
。 由於許多原因,此代碼更加強大。 您可以將Hashmap
(或任何其他抽象數據類型,例如ConcurrentHashMap<K,V>
)替換為Hashtable
。
開放原則
如果你覺得你的時間特別慷慨,你可以去:
public class C {
private Hashtable agents;
private synchronized Hashtable getAgents() {
if( this.agents == null ) {
this.agents = createAgents();
}
return this.agents;
}
public iterate() {
Iterator i = getAgentKeyIterator();
while( i.hasNext() ) {
// Code that uses i.next() ...
}
}
protected Hashtable createAgents() {
return new Hashtable();
}
private Iterator getAgentKeyIterator() {
return getAgentKeys().iterator();
}
private KeySet getAgentKeys() {
return getAgents().keySet();
}
}
這將允許子類(由其他開發人員編寫)替換他們自己使用的抽象數據類型的子類(允許系統更靈活地保持開放 - 封閉原則 ),而不必修改(或復制/浪費)您的原始工作。
這不應該是一個循環?
if (agents != null) {
Iterator iter = agents.keyset().iterator();
while (iter.hasNext()) {
//some stuffs here
}
}
或每個?
if (agents != null) {
//Assuming the key is a String
for (String key : agents.keyset()) {
//some stuffs here
}
}
確保在循環內沒有將iter
設置為null。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.