0

Given the following code

  package parkinglottest;


    public class ParkingLotTest {


        public static void main(String[] args) {
            ParkingLot p=new ParkingLot(15);
            System.out.println(p.getMax());
            Car c1=new Car(1);
            Car c2=new Car(2);
            p.addCar(c1);//at parkinglottest.ParkingLotTest.main(ParkingLotTest.java:14) 
            p.addCar(c2);
        }

    }


        package parkinglottest;


        public class ParkingLot {
            private int max;
            public ParkingLot(int max)
            {
                this.max=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 void addCar(Car c)
            {
                cars[nr++]=c; //at parkinglottest.ParkingLot.addCar(ParkingLot.java:17)
            }
            public int getMax(){
               return max;
            }
}

i get an ArrayIndexOutOfBoundsException.

7
  • What is the question? Commented Jan 11, 2014 at 12:52
  • Just because your initialization follows the constructor in the code doesn't mean that's the order of execution. Commented Jan 11, 2014 at 12:56
  • Just check in logcat and post what is the error Commented Jan 11, 2014 at 12:56
  • I do not understand why do I get outOfBoundsException when declaring the array like this : private Car[] cars=new Car[max]; Commented Jan 11, 2014 at 12:57
  • But if I declare it like this :private Car[] cars=new Car[10]; the whole programs works fine Commented Jan 11, 2014 at 12:58

7 Answers 7

3

As ZouZou mentioned, you must initialize your car array in the constructor, because the max parameter is only available in that scope.

Edit for clarification: field variables are created and initialized before the call to the constructor. So when you initialized the cars array outside the constructor you initialized it with the value of the field variable max which is initialized to 0 (because int can't be null).

package parkinglottest;


public class ParkingLot {
    private int max;
    public ParkingLot(int max)
    {
        this.max=max;
        this.cars=new Car[max];
    }

    private Car[] cars;
    int nr=0;

    public void addCar(Car c)
    {
        cars[nr++]=c; //at parkinglottest.ParkingLot.addCar(ParkingLot.java:17)
    }

    public int getMax()
    {
        return max;
    }
Sign up to request clarification or add additional context in comments.

1 Comment

The explanation is incorrect. If max wasn't available, he would get a compilation error. max is available, but it has its default field value: 0.
1

max is not intialized and is 0, then the constructor is called, but the array has been already initilized

Comments

1
public class ParkingLot {
  private int max;
  ...
  private Car[] cars=new Car[max];

Keep in mind the order of execution of initialization code:

  1. all the instance initializers run (including initializer blocks), in the order of appearance in the source;
  2. the constructor runs.

max is equal to 0 at the point you are using it to create the cars array.

Move the initialization of cars into the constructor, and watch out to use either the constructor parameter, or the instance variable after initialization.

Comments

1

You have put your array initialization outside the constructor, so before the max was set.

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];
   }

Comments

1

If you respected the usual conventions, you would write your class like this:

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;
    }
}

And it would become more obvious that at the moment the cars array is initialized, the constructor body hasn't been run yet, so max has the default value: 0. You need to initialize the array inside the constructor, after max has been initialized:

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;
    }
}

Comments

0

Max has not been initialised to anything when the array is constructed. So it throws the exception becauss max is not a viable length to create on the array, it has no value.

Initialise the array in the constructor and it should work.

The order of your program is: 1: initialise the constructor to a length of max (happening outside the constructor 2: initialise max

Initialise the array in the constructor.

Comments

0

This can be a bit of a puzzle until you figure out the Java initialization scheme.

Statements outside of any method (that aren't simple declarations) are considered to be static (if preceded by the static keyword) or instance (if no static) initializers. As such, they are collected into two unnamed methods (one for static, one not). The static initializer method is executed when the class is loaded. The instance initializer method is executed before any constructor is called.

In your case you want to leave private Car[] cars; where it is, but move cars=new Car[max]; into the constructor.

To avoid this puzzle, novices are probably well-advised to avoid using such initializers, especially ones that depend on other values.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.