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

Shelter类数组初始化触发ArrayIndexOutOfBoundsException问题咨询

构造器外初始化数组触发ArrayIndexOutOfBoundsException的原因及解决方法

原因分析

问题核心在于Java对象的初始化顺序:
当通过new Shelter("Cemali",10)创建对象时,执行流程是:

  1. 为Shelter对象分配内存,所有成员变量被设为默认值(size=0、A=null等)
  2. 执行成员变量的显式初始化代码:Animal[] A = new Animal[size];,此时size还是默认的0,所以数组A的长度被设置为0
  3. 执行构造器代码,把size赋值为10、name赋值为"Cemali"

后续调用addAnimal方法时,虽然i < size(0<10)的判断成立,但数组A的实际长度是0,尝试访问A[0]就会触发ArrayIndexOutOfBoundsException。

而正常写法中,数组仅先声明,直到构造器执行时才完成初始化,此时size已经被赋值为10,数组长度正常,自然不会触发异常。

构造器外初始化数组的可行方案

如果坚持要在构造器外完成数组初始化,可采用以下两种方式:

方案1:懒加载初始化数组

在第一次调用addAnimal方法时才初始化数组,此时构造器已经完成size的赋值:

public class Shelter {
    String name;
    int size;
    Animal[] A; // 仅声明数组
    int i = 0;

    Shelter(String name,int size){
        this.name = name;
        this.size = size;
    }

    void addAnimal(Animal animal){
        // 第一次调用时初始化数组
        if(A == null){
            A = new Animal[size];
        }
        if(i < size){
            A[i] = animal;
            i++;
        }
        else{
            System.out.println("The shelter is full.");
        }
    }

    void showAnimals(){
        if(A == null) return;
        for (Animal animal : A) {
            if(animal == null){
                break;
            }
            System.out.println(animal);
        }
    }
}

方案2:使用静态工厂方法创建对象

通过工厂方法先完成size和name的赋值,再初始化数组,完全避开构造器内初始化的限制:

public class Shelter {
    String name;
    int size;
    Animal[] A;
    int i = 0;

    // 私有构造器,避免直接实例化
    private Shelter(){}

    // 静态工厂方法
    public static Shelter create(String name, int size){
        Shelter shelter = new Shelter();
        shelter.name = name;
        shelter.size = size;
        shelter.A = new Animal[size]; // 在构造器外初始化数组
        return shelter;
    }

    void addAnimal(Animal animal){
        if(i < size){
            A[i] = animal;
            i++;
        }
        else{
            System.out.println("The shelter is full.");
        }
    }

    void showAnimals(){
        for (Animal animal : A) {
            if(animal == null){
                break;
            }
            System.out.println(animal);
        }
    }
}

使用时改为:

Shelter shelter = Shelter.create("Cemali",10);

内容的提问来源于stack exchange,提问作者hasansabbath71

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:22:50