当前位置: 首页 > 面试题库 >

为什么这段代码有时会抛出NullPointerException?

尹小云
2023-03-14
问题内容

考虑以下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
      }
    }
}

如果在语句执行之后(但在循环之前)立即将另一个线程设置agents为,则您将获得一个。通过使用访问器(与延迟初始化结合使用)可以避免这种情况。null``if``for``NullPointerException

另外,如其他人所提到的,如果可能,请避免使用有利于泛型的此类循环构造。有关详细信息,请参见其他答案。

配件提供保护

如果始终使用以下模式,则NullPointerException源代码中将永远不会包含s(另一方面,第三方代码可能会间接导致某些原因导致代码失败,这很难避免)。

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();
  }
}

这将允许子类(由其他开发人员编写)替换他们自己的正在使用的抽象数据类型的子类(使系统在遵循开放式封闭原则的情况下具有更大的灵活性),而无需修改(或复制/浪费)原始的工作。



 类似资料:
  • 我想了解为什么一段代码不会抛出NullPointerException。 请考虑以下代码: 方法被重复调用,同时以下代码在单独的线程中运行: 只有一个实例。 从不引发NullPointerException。 但是,当方法暂停时,即使暂停0毫秒,也会按预期引发NullPointerException: 我的理解是,在理论上,在检查和调用之间存在竞争条件。在实践中,如果不引入暂停(即从后续方法调用中

  • 这段代码是我用Java Swing制作的Tic-Tac-Toe程序的一部分。为什么在添加用于添加按钮的for语句时返回NullPointerException?

  • 令牌“if”的语法错误(应在此令牌之后 谢谢你的建议!

  • 如果你注释掉的内部循环,它会抛出,这显然是因为我们对集合做了更改。 如果取消注释,为什么这个循环允许我们添加这两项?运行它需要一段时间(在奔腾CPU上)大约半分钟,但它不会抛出,有趣的是,它输出: 这有点出乎意料,但它表明我们可以改变,它实际上改变了集合。知道为什么会发生这种行为吗?

  • 假设我们有以下三个类: 这将产生以下错误: 既然是整数,为什么它不选择类型?

  • 问题内容: 我正在尝试从服务器中获取数据。有时我的代码由于导致失败。这是为什么?这个问题是什么原因造成的? 问题答案: 如果在DNS服务器中发生了打cup,则可能会发生这种情况。除了使DNS服务器更强大或寻找另一台服务器之外,您还可以使用完整的IP地址代替主机名。这样,就无需根据主机名查找IP地址。但是,我宁愿解决DNS问题,也更喜欢DNS,因为IP地址可能会不时更改。