为什么NumberFormat.format会抛出NullPointerException?

时间:2014-10-22 18:14:38

标签: java nullpointerexception number-formatting

我刚发现一个非常奇怪的NullPointerException。首先,我像这样创建一个NumberFormat(注意默认的Locale将是德国,我不知道是否有帮助):

NumberFormat angleFormat = NumberFormat.getNumberInstance(Locale.UK);
angleFormat.setMaximumFractionDigits(5);
angleFormat.setMinimumFractionDigits(0);

然后,我试着用它格式化一个双。这是通过Lambda创建的新线程完成的,而angleFormat是在包含Lambda的方法中声明的。抛出异常的代码如下所示:

con.println("D" + moveId + (state.isEnemyInSightOf(e) ? "+" : "-")
        + angleFormat.format(e.getAngle()) // line 123 - error is here
        + (state.isMissileInSightOf(e) ? "+" : "-")
        + angleFormat.format(e.getSight())
        + (e.getLastShot() >= 10 || e.getLastShot() <= -1 ? "+" : "-")
        + angleFormat.format(e.getLives()));

e.getAngle()返回double,因此无法返回null。但是,我得到了这个例外:

Exception in thread "Thread-1" java.lang.NullPointerException
    at java.text.DecimalFormat.fastDoubleFormat(Unknown Source)
    at java.text.DecimalFormat.fastFormat(Unknown Source)
    at java.text.NumberFormat.format(Unknown Source)
    at server.game.Simulator.lambda$0(Simulator.java:123)
    at server.game.Simulator$$Lambda$3/23162747.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

我确定e因为异常的堆栈跟踪而不为空,它会a)先抛出一行而b)不是java.text.DecimalFormat.fastDoubleFormat < / p>

为什么有NullPointerException投掷有时,有时它可以正常工作?这意味着什么?该错误似乎是可重现的,但并不常见。

2 个答案:

答案 0 :(得分:7)

  

来自评论:我在一个循环中创建线程,每个线程都有一个不同的e但相同的NumberFormat

这似乎是您的代码遇到的间歇性问题的根源。根据{{​​3}},该类不是线程安全的,因此必须在外部同步并发访问:

  

数字格式通常不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问格式,则必须在外部进行同步。

答案 1 :(得分:2)

来自DecimalFormat

的JavaDoc
  

同步

     

十进制格式通常不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问格式,则必须在外部进行同步。

顺便问一下,这个版本的Java是什么?我没有在Java 6或7的文档中看到DecimalFormat.fastFormat()方法。