Reputation:
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
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:
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
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
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
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