Reputation: 751
Im having a problem in a program I'm making and I can't figure out what the problem is. I have made a couple of smaller test classes to try and figure out what the problem is but I dont get it. I'm sure it's some basic thing about how Arrays works or something but I can't seem to remember what. So I post the classes here and hope you guys know whats wrong. Thanks!
public class Main {
public static void main(String[] args) {
TestArray t = new TestArray(8);
t.set(1, 15);
t.print();
}
}
public class TestArray {
private Word[] a;
public TestArray(int i){
a = new Word[i];
}
public void set(int pos, long value){
a[pos].set(value);
}
public void print(){
for(Word w : a){
System.out.println(w);
}
}
}
public class Word {
private long value;
public Word(long value){
this.value = value;
}
public void set(long value){
this.value = value;
}
public String toString(){
return String.valueOf(value);
}
}
It's when I try to do t.set(1,15) the error occours and Eclipse says something is wrong with the line: a[pos].set(value);
Upvotes: 0
Views: 112
Reputation: 17309
You aren't initializing the actual elements of the Word[] a
variable. Initialize them if they're null in your TestArray.set
method.
if (a[pos] == null)
a[pos] = new Word(value);
else
a[pos].set(value);
The values of an object array in Java are initialized to null
, which is contrary to how a primitive array gets initialized (to all zeroes or equivalent thereof). So when you create the array via new Word[i]
, you're actually creating an array of null
elements, and you have to set them all accordingly.
Doing it in the set method ensures that you aren't creating any unused Word
objects. This is called lazy initialization. The other way to do it would be to initialize them all to some default value in the constructor:
public TestArray(int i){
a = new Word[i];
for (int index = 0; index < i; index++) {
a[index] = new Word(0); // Or some other default besides 0, like -1
}
}
Per your comment:
This seems to be the best way but I actually tried to do: (for-each code). Before asking here and that does not work. Why?
Your code:
public TestArray(int i) {
a = new Word[i];
for(Word w:a) {
w = new Word(0);
}
}
Doesn't work because w
isn't the actual reference like a[index]
is. In a for-each loop on an array, your code actually does this when compiled:
for (int $i = 0; $i < a.length; $i++) {
Word w = a[$i];
w = new Word(0);
}
As you can see, you're assigning a value to the local variable, w
, not to the actual element in a
, so the array isn't being changed. One remark: don't get thrown off by the $
variables because 1) $
is legal in Java variable names (though you should never use them explicitly) and 2) Java generates these variables when it compiles your code (it can be seen in the proper debuggers).
Upvotes: 4
Reputation: 150108
You allocate an array, but you do not place anything in the array elements prior to accessing the elements.
a[pos].set(value);
tries to access whatever is in a[pos], which is null.
You need to loop through the array, assigning a new instance of TestArray to each array element.
Upvotes: 3