簡體   English   中英

為什么這段代碼有時會拋出NullPointerException?

[英]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() ...
    //
  }
}

agentsHashMap

為什么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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM