Search code examples
javanullpointerexceptioncollision-detection

Sometimes throw NullPointerException, and sometimes not. How to fix?


Here's an excerpt of the init of the object:

    ...
            Rectangle b1 = tenBullets.getBounds();
    ...

Here's the getBounds() method:

public Rectangle getBounds() {
    return new Rectangle(x, y, 200, 25);
}

And here is the console message:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at test.game.Board.checkCollisions(Board.java:75)
at test.game.Board.actionPerformed(Board.java:53)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Board.java:75 is when the getBounds() method is called. Sometimes the exception is thrown, and 1 out of the 10th time it's not. Any fixes?


Solution

  • The NullPointerException is thrown because tenBullets is null when that method is called - and you're trying to invoke a method on a null object (which isn't possible, and leads to the exception).

    In order to fix this, you need to do one of two things:

    1. Change the preceding behaviour, so that tenBullets is always assigned a value before you call getBounds() on it. This is the option to choose is tenBullets should never be null at this point.
    2. Make the code in the question tolerant of null - check if (tenBullets == null), and take some alternative action if this is true. This is the option to choose if null might well be a sensible value (perhaps it may or may not be initialised); if so, you have to deal with that eventuality.

    Without understanding either the intent or the context of the code, it's impossible to give concrete recommendations. However, if tenBullets is a field (as opposed to a local variable), consider whether it ever makes sense for it to be unset (or modified); and if not, declare it final. This will guarantee that it is initialised within the constructor and holds that value consistently.

    In general, reducing the number of mutable fields/variables makes it much easier to reason about a program, because you need to be less aware of what state it may or may not be in at the time of execution. It sounds like that's your problem here, that tenBullets is being assigned by some other bit of code, at some point, and there's no definitive ordering.