【问题标题】:Calling a method from a class array gives NullPointerException从类数组调用方法会产生 NullPointerException
【发布时间】:2026-01-28 00:25:02
【问题描述】:

我一直在寻找这个问题,但我找不到解决方案。我正在尝试构建一个迷你游戏,并且我有一种创建平台的方法。我有一个包含每个平台参数的类,并且我创建了一个类数组,这样我就可以同时拥有多个平台。

问题:当我尝试通过发送我想要的参数来调用构建平台的方法时,它给了我一个NullPointerException。该方法以前可以使用,但是由于所有内容都是静态的,因此我无法拥有该类的多个实例,现在我从平台类中删除了静态字段,并且每次调用该方法时它都会给我NullPointerException

我复制了给我错误的部分代码,错误如下:

public static void main(String[] args) {
        Game ex = new Game();
        new Thread(ex).start();
    }

在游戏类中:

public Load_Stage load = new Load_Stage();
public Game() {
        -other variables initializatin-
        Initialize_Items();
        load.Stage_1(); // <--- problem this way

在 Load_Stage 类中:

public class Load_Stage {
    public Platforms plat = new Platforms();

    public void Stage_1(){    
        Stage_Builder.Build_Platform(200, 500, 300, plat.platform1);
        Stage_Builder.Build_Platform(100, 200, 100, plat.platform1);
    }

}

在 Stage_Builder 类内部:

public class Stage_Builder {

    public static final int max_platforms = 10;
    public static Platform_1[] p1 = new Platform_1[max_platforms];
    public static boolean[] platform_on = new boolean[max_platforms];    

    public Stage_Builder() {
        for (int c = 0; c < platform_on.length; c++) {
            platform_on[c] = false;
        }
    }
    public static void Build_Platform(int x, int y, int width, ImageIcon[] type) { // BUILDS A PLATFORM

        for (int b = 0; b < max_platforms; b++) {
            if (platform_on[b] == false) { 
                p1[b].Construct(x, y, width, type); // <-- NullPointerException here
                platform_on[b] = true; 
                break;
            }
        }
    }
}

先谢谢了。

编辑:这是 Platform_1 类(抱歉忘记了):

public class Platform_1 {

    private int platform_begin_width = 30;
    private int platform_middle_width = 20;
    public int blocks_number = 0;
    public ImageIcon[] platform_floors = new ImageIcon[500];
    private int current_width = 0;
    public int [] platform_x = new int [500];
    public int platform_y = 0;
    public int platform_width = 0;

    public void Construct(int x, int y, int width, ImageIcon [] type) {        
        platform_width = width;
        platform_y = y;
        for (int c = 0; current_width <= platform_width; c++) { 
            if (c == 0) {
                platform_x[c] = x;
                platform_floors[c] = type[0];
                current_width += platform_begin_width;
            } else if ((current_width + platform_middle_width) > platform_width) {
                platform_floors[c] = type[2];
                blocks_number = c + 1;
                platform_x[c] = current_width + x;
                current_width += platform_middle_width;
            } else {
                platform_floors[c] = type[1];
                platform_x[c] = current_width + x;
                current_width += platform_middle_width;
            }
        }        
    }
}

还有 Platforms 类:

public class Platforms {

    public ImageIcon[] platform1 = {new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/begin.png"),
        new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/middle.png"),
        new ImageIcon("Resources/Sprites/Stage_Objects/Platform1/end.png")};
}

【问题讨论】:

    标签: java arrays class static netbeans-7


    【解决方案1】:

    问题和解决方案都很明显。

    public static Platform_1[] p1 = new Platform_1[max_platforms];
    

    这行代码执行后,p1 是一个 Platform_1 类型的引用数组都是空的

    执行这行代码马上告诉你:

                p1[b].Construct(x, y, width, type); // <-- NullPointerException here
    

    解决方案是初始化p1 数组以指向Platform_1 的非空实例。

    这样的事情会起作用:

    for (int i = 0; < p1.length; ++i) {
        p1[i] = new Platform1();
    }
    

    【讨论】:

    • 很抱歉忘记了 p1 数组代码。我编辑了帖子。我会检查你的解决方案,看看它是否有效,谢谢:)
    • 好的,如何初始化 p1 以指向 Platform_1 的非空实例?我知道你的意思,我只是不确定如何实施解决方案
    • 我像您的代码一样尝试过,但没有成功。我通过执行“public static Platform_1[] p1 = {new Platform_1(), new Platform_1(), new Platform_1()} ...}”来填充它并且它有效。但是该解决方案根本没有效率=/
    • 我不知道“没用”是什么样的。这是一个例子。您是否将该循环放入静态初始化块中?
    • 哦。对不起,我在构造函数中做了一个“for”循环,我没有注意到你的静态初始化块。现在成功了,非常感谢!
    【解决方案2】:

    我没有看到您在 Stage_Builder 类中的 p1 数组中的位置。

    另一种可能性(不太可能,但如果您没有显示所有内容,则可能)是您未显示的 Platform 类中的某些内容未初始化,并且在您调用 Construct 时会中断。

    另外,以下似乎有问题

    public static Platform_1[] p1 = new Platform_1[max_platforms];
    public static boolean[] platform_on = new boolean[max_platforms];    
    
    public Stage_Builder() {
       for (int c = 0; c < platform_on.length; c++) {
           platform_on[c] = false;
       }
    }
    

    您似乎声明了静态变量p1platform_on,但您只在构造函数中填充platform_on。因此,第一次创建 Stage_Builder 实例时,您将使用所有 false 填充一个静态数组,并且不要在另一个静态数组中放入任何内容...

    在静态块中填充这些静态变量

    // static var declarations
    
    static {
       // populate static arrays here.
    }
    

    【讨论】:

    • 很抱歉忘记了 p1 数组代码。我编辑了帖子。我会检查你的解决方案,看看它是否有效,谢谢:)
    • 你在哪里填充 p1 数组?
    • 我实际上...不填充它,我现在就做,看看是否有效。我认为这不是问题,因为我做了类似以前的事情并且我使用相同的逻辑做了......但我想我会按照 Kosta 的建议使用 ArrayList,看看是否可行。谢谢。
    • 不,正如这个和其他答案所说,p1 数组中缺少东西是导致问题的原因。您正在尝试引用数组中的某些内容,但其中没有任何内容。
    • 我通过执行“public static Platform_1[] p1 = {new Platform_1(), new Platform_1(), new Platform_1()} ...}”来填充它并且它有效,但我需要一个更好的解决方案,一个动态的,以防我想更改数组的大小,我尝试使用 for 循环与静态 platform_on 一起填充,但它没有那样工作。有什么建议吗?
    【解决方案3】:

    您调用消息的数组从未填充。

    你有

    public static Platform_1[] p1 = new Platform_1[max_platforms];
    

    所以p1

    p1[0] = null
    p1[1] = null
     .
     .
     .
    p1[max_platforms] = null
    

    你试着打电话

    p1[b].Construct(x, y, width, type);
    

    这是

    null.Construct(...);
    

    您需要先在数组上初始化该索引。

    p1[b] = new Platform_1();
    p1[b].Construct(...);
    

    【讨论】:

    • 谢谢,这似乎是问题所在。我现在就去处理它:D
    【解决方案4】:

    首先,您的问题是 p1[b] 很可能为空,正如 duffymo 指出的那样。

    其次,您正在以一种非常奇怪的方式使用数组。怎么样

    a) 删除 Stage_Builder

    b) 相反,在某处有一个 ArrayList

    c) Build_Platform1() 的等价物看起来像这样,那么:

    p1.add(new Platform1(x, y, width, type);
    

    d) 没有 if on[i],没有 max_platforms,没有添加平台的 for 循环(如果您实际上有几百个平台,则后者是一个糟糕的性能问题)

    【讨论】:

    • 哇,似乎是一个不错的改进。谢谢,我实际上之前没有处理过 ArrayLists,但是我按照你的建议做。至于问题,我用 p1 (Platform_1) 类代码编辑了帖子。据我所知,一切都在那里正确初始化。谢谢:D