You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java报错Index 0 out of bounds for length 0的原因及解决

为什么我的ConnectionManager会抛出NullPointerException,而Test类的相同逻辑却正常运行?

先看这段可以正常运行的代码:

class Test {
    static int size;
}

public class E08_ConnectionApp {
    public static void main(String[] args) {
        Test.size = Integer.parseInt(args[0]);
        Test[] test = new Test[Test.size];
        for (int i = 0; i < Test.size; i++) test[i] = new Test();
    }
}

但当我实现类似逻辑的ConnectionManager时,却抛出了NullPointerException,错误出现在ConnectionManager构造方法的循环行:

for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);

以下是无法运行的完整代码:

class Connection {
    private int ID;

    private Connection(int ID) {
        this.ID = ID;

        print("Connection number " + ID + " created.");
    }

    static Connection createNewConnection(int ID) { return new Connection(ID); }

    Connection getConnection() { return this; }

    public int getID() {
        return ID;
    }
}
class ConnectionManager {
    private int size;

    public ConnectionManager(int size) {
        this.size = size;

        for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);
    }

    private Connection[] connections = new Connection[size];

    public Connection getAvailableConnection() {
        for (int i = 0; i < size; i++)
            if (connections[i] != null) {
                Connection temp = connections[i].getConnection();
                connections[i] = null;
                print("Connection #" + temp.getID() + " fetched.");
                return temp;
            }

        print("No connections available...");
        return null;
    }
}

public class E08_ConnectionApp {
    public static void main(String[] args) {
        ConnectionManager connectionManager = new ConnectionManager(Integer.parseInt(args[0]));
    }
}

我原本以为是数组虽然分配了空间但都是null引用,但我明明就是要在循环里初始化这些引用。我试过排查项目设置、怀疑IDE bug,但都不是问题,而且Test类的逻辑一直正常,实在搞不懂哪里错了,正确的实现方式应该是什么?


问题原因

核心问题在于Java中类成员的初始化顺序:

  • 创建ConnectionManager对象时,会先初始化所有类成员变量,再执行构造方法。
  • 你的connections数组是在构造方法之后定义的成员变量,初始化connections时,size还没被构造方法赋值(此时size是默认值0),导致connections是一个长度为0的空数组。
  • 当构造方法里的循环尝试访问connections[i]时,数组长度为0,直接触发异常。

而Test类的逻辑之所以正常,是因为Test.size是静态变量,你在创建数组前已经给它赋值,且数组是在main方法里创建的,不存在成员初始化顺序的冲突。

正确的实现方式

调整数组的初始化时机,把数组的创建放到构造方法里,确保使用已经赋值的size:

修改后的ConnectionManager类:

class ConnectionManager {
    private int size;
    private Connection[] connections; // 先声明数组,不初始化

    public ConnectionManager(int size) {
        this.size = size;
        connections = new Connection[size]; // 构造方法内用已赋值的size初始化数组
        for (int i = 0; i < size; i++) connections[i] = Connection.createNewConnection(i + 1);
    }

    public Connection getAvailableConnection() {
        for (int i = 0; i < size; i++)
            if (connections[i] != null) {
                Connection temp = connections[i].getConnection();
                connections[i] = null;
                print("Connection #" + temp.getID() + " fetched.");
                return temp;
            }

        print("No connections available...");
        return null;
    }
}

这样修改后,数组会用正确的size值初始化,后续循环就能正常给数组元素赋值,不会再触发异常。


内容的提问来源于stack exchange,提问作者Нормальный дневник

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 14:20:01