编辑我正在添加源代码的pastebin,以便更容易查看我的代码。
起始类[http://pastebin.com/Q7w3pbC5]
机器人[http://pastebin.com/BbZRFM5K]
敌人[http://pastebin.com/N98Ly1uY]
我是一个新的Java程序员,刚刚遇到他的第一个空指针异常。我在课堂上进行了一次疯狂的追逐,但没有提出任何建议。
我正在关注Kilobolt的Java游戏开发教程(http://www.kilobolt.com/game-development-tutorial.html)并且我已经到了最后。不幸的是,我在游戏的敌人类的更新功能中得到了一个空指针异常。如果需要,我可以发布完整的源代码,但这里是我认为最相关的片段 空指针来自
} else if (Math.abs(robot.getCenterX() - centerX) < 5) {
我做了一些调查,发现敌人类内的打印机器人打印为空。我们必须深入了解。我在这里从getter函数中获取机器人:
private Robot robot = StartingClass.getRobot();
StartingClass中的相应函数是:
public static Robot getRobot() {
return robot;
}
将机器人定义为:
private static Robot robot;
我可以告诉机器人在StartingClass中不是null,因为我可以调用相同的getter函数并打印出结果。我不明白为什么它不会通过getter函数延续。
谢谢。
答案 0 :(得分:1)
检查Robot中的CenterX变量是否在使用之前启动。
答案 1 :(得分:1)
使用该片段了解情况很复杂。 但分析情况
我假设你有一个班级
class static StartingClass{
private static Robot robot;
public static Robot getRobot() {
return robot;
}
}
在某些类中你有
class someClass{
someMethod(){
//Business logic
if{
//Business logic x2
}else if (Math.abs(robot.getCenterX() - centerX) < 5) { //NULLPOINTER
}
}
}
如果你得到一个nullpointer,并且你还说那个momment机器人是null,问题很明显,你不能执行null.getCenterX(),显然会抛出异常。 另外,你说在启动类中机器人不是空的,但实际上没有意义,因为如果在StartingClass机器人不为null,你应该得到机器人的实例。
我们有三种可能的修复方法(取决于您应用的业务逻辑):
1)假设机器人可能为null,我们检查机器人是否为空:
class someClass{
someMethod(){
//Business logic
if{
//Business logic x2
}else if (robot!= null && Math.abs(robot.getCenterX() - centerX) < 5) { //NULLPOINTER
}
}
}
2)假设错误是我们在分配之前得到了机器人,我们在方法执行之前就准备好了机器人:
class someClass{
someMethod(){
//Business logic
private Robot robot = StartingClass.getRobot();
if{
//Business logic x2
}else if (robot && Math.abs(robot.getCenterX() - centerX) < 5) { //NULLPOINTER
}
}
}
3)在开始时加入somemethod(){
private Robot robot = StartingClass.getRobot();
if(robot==null){
return
}
答案 2 :(得分:1)
首先,让我们注意到在2个不同的类中有2个不同的字段robot
。类StartingClass
中的一个静态和第一个类中的一个非静态(假设类X
)。
现在,由于X类中的机器人字段定义如下:
private Robot robot = StartingClass.getRobot();
从X类创建新对象时,StartingClass.getRobot()
立即被称为 。因此,您必须在StartingClass
之前初始化机器人字段你从类X创建一个新对象。
您可以在StartingClass
中初始化机器人,如下所示:
public static void init() {
try {
robot = new Robot();
} catch (AWTException ex) {
System.err.println("Error");
}
}
答案 3 :(得分:1)
你说:“我可以告诉机器人在StartingClass中不是null,因为我可以调用相同的getter函数并打印出结果。”
我不知道你的意思是“打印出结果”。你可以告诉引用不是null的方法是实际进行空检查,我认为你没有。
你说你通过以下方式“定义”了机器人:
private static Robot robot;
但请注意,机器人为空。这只是一个名称/句柄。它实际上并没有引用一个对象。因此,在将对象分配给“robot”之前,调用getter将只返回null。
我瞥了一眼敌人班。看起来代码总是像
那样private static Robot robot = GameScreen.getRobot();
只要右侧返回Robot对象,“robot”将引用实际对象。看起来你可能无意中删除了那部分。