为什么NumberFormat.format会抛出NullPointerException?

msr*_*rd0 7 java nullpointerexception number-formatting

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

NumberFormat angleFormat = NumberFormat.getNumberInstance(Locale.UK);
angleFormat.setMaximumFractionDigits(5);
angleFormat.setMinimumFractionDigits(0);
Run Code Online (Sandbox Code Playgroud)

然后,我试着用它格式化一个双.这是通过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()));
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

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

为什么有时会NullPointerException抛出一些东西,有时它会毫无问题地工作?这意味着什么?该错误似乎是可重现的,但不是很常见.

das*_*ght 8

从评论:我在循环中创建线程,每个线程不同e但相同NumberFormat

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

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