简体   繁体   中英

Why does NumberFormat.format throw an NullPointerException?

I've just found a very strange NullPointerException . First, I create a NumberFormat like this (note that the default Locale would be Germany, I don't know if that helps):

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

Then, I tried to format a double with it. This is done with a new Thread created by a Lambda, while angleFormat is declared at the method containing the Lambda. The code where the Exception is thrown looks like this:

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() returns a double , so it can't return null. However, I get this Exception:

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)

I'm sure that e isn't null because of the Exception's stacktrace, it would a) be thrown one line earlier and b) not at java.text.DecimalFormat.fastDoubleFormat

Why is there a NullPointerException beeing thrown sometimes , and sometimes it works without problems? And what does that mean? The error seems to be reproducable, but not very often.

From the comments: I create the threads in a loop with each one a different e but the same NumberFormat

This appears to be the source of intermittent issues that your code is experiencing. According to the documentation of NumberFormat , the class is not thread-safe, so concurrent access must be synchronized externally:

Number formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

From the JavaDoc for DecimalFormat

Synchronization

Decimal formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

By the way, which version of Java is this? I don't see a DecimalFormat.fastFormat() method in the docs for either Java 6 or 7.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM