java.lang.NullPointerException但对象不为null(我想)

时间:2012-07-07 15:46:07

标签: java

我的上一个项目(以及最大的:)是Ping Pong游戏。 我正在尝试实现“AI”,但由于

,我不能这样做
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)

我认为我已经编写了完整的代码,但肯定存在错误。

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

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

Player.java - pastebin.com/7QeiNciz

Ai.java - pastebin.com/xsGhJ7Zb(只有两个超链接,防止垃圾邮件)

代码写得不好,我希望你不会去(得到?)盲目:)

问候, 阿德里安

3 个答案:

答案 0 :(得分:8)

你有竞争条件。

当你调用Ball构造函数时,会立即调用movement()来调度有问题的代码(诚然在不同的线程中)。所有这些都发生在分配了 Main之前Main.player构造函数的中间。所以在这里movement()行:

if(main.player.intersects(main.ball) && hitP == false){
如果计时器线程足够快地启动,则

... main.player仍然为空,因此main.player.intersects调用会抛出异常。 (main.ball也是null,但实际不会导致你看到的问题。但它仍然是一个问题。)

要学习一些课程:

  • 不要在构造函数中做太多事情
  • 理想情况下,尽量避免创建此类循环引用,或者如果 拥有,请确保在开始实际工作之前初始化所有内容
  • 让您的类名更有意义:Main可以只是是程序的入口点,但创建类型为{{1}的对象对我来说听起来很可疑。什么 一个Main?你会怎么描述它?
  • 不要滥用继承 - Main没有理由延伸Ball(你说Thread但你没有在{implements Runnable中提供run()方法1}})
  • 避免与Balltrue进行比较 - 写false代替if (foo)if (foo == true)代替if (!foo)
  • 使您的变量名称有意义 - 根据我之前的评论,在同一个类中调用if (foo == false)变量Rectangle,您有一个名为player的{​​{1}}变量正在询问麻烦
  • 将所有变量设为私有,如果需要,则通过属性公开它们。 (除非你真的需要,否则不要暴露它们)
  • 缩进非常重要 - 正确缩进代码会使其更容易阅读
  • 直到你真的熟悉语言的基础知识,避免线程化 - 这很难,并且可以引入各种微妙的问题

答案 1 :(得分:2)

在代码中,您在第17行调用ball.movement(),然后在第18行分配main非空值。

答案 2 :(得分:0)

此行:主线18中的player = new Rectangle(p.getX(), p.getY(), 10, 50);必须在主线15中b = new Ball(this);之前。否则当您调用移动时,播放器为空。