ahoj pepiczki
ahoj pepiczki

Reputation: 309

java.lang.NullPointerException but object isn't null (I suppose)

My last project (and the biggest :)) is the Ping Pong game. I'm trying to implement "AI", but I can't do this because of

Exception in thread "Timer-0" java.lang.NullPointerException
    at main.Ball$1.run(Ball.java:25)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

I think I've written whole code well, but there must be something wrong.

Main.java - http://pastebin.com/nvHwQAFD

Ball.java - http://pastebin.com/cgE5r5eW

Player.java - pastebin.com/7QeiNciz

Ai.java - pastebin.com/xsGhJ7Zb (only two hyperlinks, spam prevention)

The code isn't written in good style and I hope you won't go (get?) blind :)

Greetings, Adrian

Upvotes: 2

Views: 2343

Answers (3)

Jon Skeet
Jon Skeet

Reputation: 1499770

You've got a race condition.

When you call the Ball constructor, that immediately calls movement() which schedules the code which is problematic (admittedly in a different thread). All of this happens in the middle of the Main constructor before Main.player has been assigned. So in the line of movement() here:

if(main.player.intersects(main.ball) && hitP == false){

... main.player is still null if the timer thread starts quickly enough, so the main.player.intersects call throws the exception. (main.ball is also null, but that doesn't actually cause the problem you're seeing. It's still an issue though.)

A few lessons to learn:

  • Don't do too much in a constructor
  • Ideally, try to avoid creating this sort of cyclical reference, or if you have to have one, make sure everything's initialized before you start doing real work
  • Make your class names more meaningful: Main is fine as just an entry point to a program, but creating an object of type Main sounds very suspicious to me. What is a Main? How would you describe it?
  • Don't abuse inheritance - there's no reason why Ball should extend Thread (you say implements Runnable but you don't provide a run() method yourself in Ball)
  • Avoid comparisons with true or false - write if (foo) instead of if (foo == true) and if (!foo) instead of if (foo == false)
  • Make your variable names meaningful - as per my comment earlier, calling a Rectangle variable player in the same class that you have a Player variable called p is asking for trouble
  • Make all your variables private, exposing them through properties if you need to. (Don't expose them unless you really do need to though)
  • Indentation is important - indenting your code properly makes it much easier to read
  • Until you're really comfortable with the basics of the language, avoid threading - it's hard, and can introduce all kinds of subtle problems

Upvotes: 8

sebsebmc
sebsebmc

Reputation: 112

This line: player = new Rectangle(p.getX(), p.getY(), 10, 50); in Main line 18 has to go before b = new Ball(this); in Main line 15. otherwise player is null when you call movement.

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

In your code you call ball.movement() on line 17 before assigning main a non-null value on line 18.

Upvotes: 2

Related Questions