java.lang.ArrayIndexOutOfBoundsException:0

java.lang.ArrayIndexOutOfBoundsException:0,java,arrays,indexoutofboundsexception,Java,Arrays,Indexoutofboundsexception,给定以下代码 package parkinglottest; 公共类停车场测试{ 公共静态void main(字符串[]args){ 停车场p=新停车场(15); System.out.println(p.getMax()); 车辆c1=新车(1); 车辆c2=新车(2); p、 addCar(c1);//在parkinglottest.parkinglottest.main(parkinglottest.java:14) p、 addCar(c2); } } 包装停车试验; 公共停车场{ 私人

给定以下代码

package parkinglottest;
公共类停车场测试{
公共静态void main(字符串[]args){
停车场p=新停车场(15);
System.out.println(p.getMax());
车辆c1=新车(1);
车辆c2=新车(2);
p、 addCar(c1);//在parkinglottest.parkinglottest.main(parkinglottest.java:14)
p、 addCar(c2);
}
}
包装停车试验;
公共停车场{
私人int max;
公共停车场(国际最大)
{
这个。max=max;
}
私家车[]cars=新车[max];//如果我不输入“max”,而是输入任何其他正整数,则效果很好。
int nr=0;
公共车辆(c车)
{
cars[nr++]=c;//在parkinglottest.ParkingLot.addCar(ParkingLot.java:17)
}
公共int getMax(){
返回最大值;
}
}

我得到一个ArrayIndexOutOfBoundsException。

max未初始化,为0,然后调用构造函数,但数组已初始化

您已将数组初始化置于构造函数之外,因此在设置max之前

public class ParkingLot {
   private int max;
   private int nr;
   private Car[] cars; // it was like saying = new Car[0], because max was 0.

   public ParkingLot(int max)
   {
      this.max = max;
      this.cars = new Car[max];
   }
请记住初始化代码的执行顺序:

  • 所有实例初始值设定项(包括初始值设定项块)都按照在源代码中出现的顺序运行
  • 构造函数运行
  • max
    在使用它创建
    cars
    数组时等于
    0


    cars
    的初始化移动到构造函数中,并注意在初始化后使用构造函数参数或实例变量。

    正如邹祖所提到的,必须在构造函数中初始化car数组,因为
    max
    参数仅在该范围内可用

    编辑以澄清:在调用构造函数之前创建并初始化字段变量。因此,当您在构造函数外部初始化cars数组时,您使用字段变量
    max
    的值初始化它,该变量被初始化为0(因为int不能为null)


    如果您遵守通常的惯例,您可以这样编写您的类:

    public class ParkingLot {
        private int max;
        private Car[] cars = new Car[max];//if instead of "max" i put any other positive integer, it works just fine.
        int nr = 0;
    
        public ParkingLot(int max) {
            this.max = max;
        }
    
        public void addCar(Car c) {
            cars[nr++] = c; 
    
        public int getMax() {
            return max;
        }
    }
    
    更明显的是,在初始化
    cars
    数组的那一刻,构造函数主体还没有运行,因此max具有默认值:0。初始化
    max
    后,需要在构造函数内初始化数组:

    public class ParkingLot {
        private int max;
        private Car[] cars;
        int nr = 0;
    
        public ParkingLot(int max) {
            this.max = max;
            this.cars = new Car[max];
        }
    
        public void addCar(Car c) {
            cars[nr++] = c;
        }
    
        public int getMax() {
            return max;
        }
    }
    

    构造数组时,Max未初始化为任何值。因此它抛出异常,因为max不是在数组上创建的可行长度,它没有值

    在构造函数中初始化数组,它应该可以工作

    您的程序顺序为: 1:将构造函数初始化为最大长度(发生在构造函数外部 2:初始化最大值


    在构造函数中初始化数组。

    这可能是一个难题,直到您了解Java初始化方案

    任何方法之外的语句(不是简单的声明)都被认为是静态的(如果前面有
    static
    关键字)或实例(如果没有
    static
    )初始值设定项。因此,它们被收集到两个未命名的方法中(一个用于
    static
    ,一个不用于).static初始化器方法在类加载时执行。实例初始化器方法在调用任何构造函数之前执行

    在您的情况下,您希望将
    private Car[]cars;
    留在它所在的位置,但将
    cars=new Car[max];
    移动到构造函数中


    为了避免这个难题,新手最好避免使用这样的初始值设定项,特别是那些依赖于其他值的初始值设定项。

    问题是什么?仅仅因为您的初始化遵循代码中的构造函数并不意味着这就是执行顺序。只需检查logcat并公布错误是什么我不明白为什么要这样做当像这样声明数组时,我会有边界异常:private Car[]cars=new Car[max];但是如果我像这样声明:private Car[]cars=new Car[10];整个程序运行良好解释是错误的。如果max不可用,他将得到一个编译错误。max可用,但它有其默认字段值:0。
    public class ParkingLot {
        private int max;
        private Car[] cars = new Car[max];//if instead of "max" i put any other positive integer, it works just fine.
        int nr = 0;
    
        public ParkingLot(int max) {
            this.max = max;
        }
    
        public void addCar(Car c) {
            cars[nr++] = c; 
    
        public int getMax() {
            return max;
        }
    }
    
    public class ParkingLot {
        private int max;
        private Car[] cars;
        int nr = 0;
    
        public ParkingLot(int max) {
            this.max = max;
            this.cars = new Car[max];
        }
    
        public void addCar(Car c) {
            cars[nr++] = c;
        }
    
        public int getMax() {
            return max;
        }
    }