user4192303
user4192303

Reputation:

Java Variable array length

I am having trouble compiling my java project because the array length integer (which is a variable) is not substituting correctly in my Object array.

import java.util.Arrays;

public class ObjectList {
    private int N;
    private Object[] fractionList = new Object[N];

    public ObjectList(int n){
        this.N = n;
    }

    public int capacity(){
        return this.N;
    }

    public void setN(int n){
    this.N = n;
    }

    public String toString(){
        return Arrays.toString(fractionList);
    }
}

public class FractionDriver {
    public static void main(String[] args){

    // creates the object list, sets N to 4
    ObjectList list = new ObjectList(4);

    System.out.println("The Objectlist has " + list.capacity() + " lines");

    // prints the array
    System.out.println(list.toString());
    }
}

this is what the compiler outputs:

The ObjectList has 4 lines
[]

Because of this, I cannot add any objects to my array. The compiler throws an ArrayIndexOutOfBoundsException: 0 and tells me that there are no elements in the array.

If I choose to replace N in the object array instance variable, like so:

private Object[] fractionList = new Object[4];

The compiler is happy and sets the array length to 4.

What am I doing wrong?

Upvotes: 2

Views: 902

Answers (4)

Mathias Bader
Mathias Bader

Reputation: 3826

The problem is that the line

private Object[] fractionList = new Object[N];

is executed before your Constructor. The order of initialization is always as follows:

  1. If there is a superclass - initialize it first
  2. Static variable declaration and static initializers in order of appearance
  3. Instance variable declaration and instance initializers in order of appearance
  4. The constructor.

You wanted the code in your constructor (4) to set the array length, but the array was already created in your instance variable (3).

I recommend the following:

public class ObjectList {
    private int N;
    private Object[] fractionList;

    public ObjectList(int n){
        fractionList = new Object[n];
        this.N = n;
    }

    public int capacity(){
        return this.N;
    }

    public void setN(int n){
        // might want to copy content from old array to new one here
        fractionList = new Object[n];
        this.N = n;
    }

    public String toString(){
        return Arrays.toString(fractionList);
    }
}

If you want to comply to Java Beans, I'd also recommend to rename the capacity() method to getCapacity().

Upvotes: 1

wings
wings

Reputation: 801

well... in simple word, when the Object[] fractionList is initialized, the value of field N is "invisible", because its value will not be set until this.N = n; is invoked, unlike literal number 4, which is compile-time constant.

You can pass a parameter N to the constructor to initialize the array. Something like:

public ObjectList(int n){
    this.fractionList = new Object[n];
}

Upvotes: 0

M A
M A

Reputation: 72844

First this is not a compilation error. The program is compiling fine. The problem is that the array fractionList gets initialized before the body of the constructor is called where the variable N is set.

You can move the initialization to the constructor:

private Object[] fractionList;


public ObjectList(int n) {
    this.N = n;
    fractionList = new Object[N];
}

Upvotes: 0

Eran
Eran

Reputation: 393771

You can create the array instance in your constructor, where the length is already known :

private Object[] fractionList;

public ObjectList(int n){
    this.N = n;
    this.fractionList = new Object[n];
}

However, you may also want to recreate the array when you change the value of N :

public void setN(int n){
    this.N = n;
    // consider copying data from the old array to the new array
    this.fractionList = new Object[n];
}

Upvotes: 3

Related Questions