Consider the following class:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
public void print(DataStructureIterator iter) {
while(iter.hasNext()) {
System.out.print(iter.next() + " ");
}
System.out.println();
}
interface DataStructureIterator extends java.util.Iterator<Integer> { }
// Inner class implements the DataStructureIterator interface,
// which extends the Iterator<Integer> interface
private class EvenIterator implements DataStructureIterator {
// Start stepping through the array from the beginning
private int nextIndex = 0;
public boolean hasNext() {
// Check if the current element is the last in the array
return (nextIndex <= SIZE - 1);
}
public Integer next() {
// Record a value of an even index of the array
Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
// Get the next even element
nextIndex += 2;
return retValue;
}
}
public static void main(String s[]) {
// Fill the array with integer values and print out only
// values of even indices
DataStructure ds = new DataStructure();
ds.print(
new DataStructure.DataStructureIterator() {
private int nextIndex = 1;
public boolean hasNext() {
return (nextIndex <= ds.size() - 1);
}
public Integer next() {
//int retValue = arrayOfInts[nextIndex]; // this won't work:
// non-static variable arrayOfInts cannot be referenced from a static context
int retValue = ds.get(nextIndex);
nextIndex += 2;
return retValue;
}
}
);
}
}
Compiling this, I get:
error: non-static variable arrayOfInts cannot be referenced from a static context
The compiler complains about the access to the arrayOfInts variable from the anonymous class that's in the main method.
My question is: Ok I understand that I can't access a non-static variable from a static context - it completely makes sense. But in this case, I'm not actually accessing the variable from the static context. Rather, I'm passing a piece of code - an anonymous class - to a non-static method. The non-static method can definitely access a non-static variable, so why isn't it possible?
Java doesn't consider what you are doing with the instance that you are creating, to determine whether you can access an non-static field.
For all Java knows, you could be assigning the instance of the anonymous class to a local variable:
What would
foo.next()do in this case? There is no instances ofDataStructureanywhere!That said, there is an instance of
DataStructurein your code -ds. You probably meant to access thearrayOfIntsin that instance, so just dods.arrayofIntsinstead.Note that the use of
arrayOfIntsinsideEvenIteratoris valid becauseEvenIteratoris a inner class ofDataStructure. Note thatDataStructureIterator, which is also nested inDataStructure, is not an "inner interface". There is no such thing as "inner interfaces".DataStructure.DataStructureIteratoris just another regular type.To create an instance of
EvenIterator, you need an instance ofDataStructurefirst. This instance ofDataStructureis called the enclosing instance ofEvenIterator.Because
EvenIteratoris accessing thearrayOfIntsof its enclosing instance, and not whatever instance you are callingprinton, this can lead to some unexpected results: