提问人:YoavKlein 提问时间:7/7/2023 更新时间:7/7/2023 访问量:85
Java:在静态上下文中访问匿名类中的非静态字段
Java: accessing a non-static field in an anonymous class in a static context
问:
请考虑以下类:
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;
}
}
);
}
}
编译这个,我得到:
error: non-static variable arrayOfInts cannot be referenced from a static context
编译器抱怨从 main 方法中的匿名类访问变量。arrayOfInts
我的问题是:好的,我知道我无法从静态上下文访问非静态变量 - 这完全有意义。 但在本例中,我实际上并没有从静态上下文访问变量。相反,我正在将一段代码(一个匿名类)传递给一个非静态方法。非静态方法肯定可以访问非静态变量,那么为什么不可能呢?
答:
您正在从静态方法中创建一个匿名类,并尝试将非静态字段传递给实现,这就是您收到编译错误的原因。而 EvenIterator 类相对于 DataStructure 是内部的,因此它意味着绑定到 DataStructure 类的实例并可以访问其非静态变量。
内部类和嵌套类的规范
与实例方法和变量一样,内部类与其封闭类的实例相关联,并可以直接访问该对象的方法和字段。
相反,我正在将一段代码(一个匿名类)传递给一个非静态方法
Java 不会考虑您对正在创建的实例执行的操作,以确定您是否可以访问非静态字段。
据 Java 所知,您可以将匿名类的实例分配给局部变量:
public static void main(String[] args) {
var foo = new DataStructure.DataStructureIterator() {
public boolean hasNext() {
...
}
public Integer next() {
int retValue = arrayOfInts[nextIndex]; // this won't work:
...
}
};
foo.next();
}
在这种情况下会怎么做?任何地方都没有实例!foo.next()
DataStructure
也就是说,在您的代码中有一个实例 - 。在这种情况下,您可能打算访问,因此请改为访问。DataStructure
ds
arrayOfInts
ds.arrayofInts
请注意,inside 的使用是有效的,因为 是 的内部类。请注意,,它也嵌套在 中,它不是“内部接口”。没有“内部接口”这样的东西。 只是另一种常规类型。arrayOfInts
EvenIterator
EvenIterator
DataStructure
DataStructureIterator
DataStructure
DataStructure.DataStructureIterator
要创建 的实例,您需要一个 的实例。此实例称为 的封闭实例。EvenIterator
DataStructure
DataStructure
EvenIterator
因为正在访问其封闭实例,而不是您正在调用的任何实例,这可能会导致一些意外结果:EvenIterator
arrayOfInts
print
DataStructure ds1 = new DataStructure();
DataStructure ds2 = new DataStructure();
EvenIterator iter = ds1.new EvenIterator(); // enclosing instance is ds1
ds2.print(iter); // prints the elements of ds1, not ds2!
评论
new DataStructure.DataStructureIterator()
应该肯定吗?ds.new DataStructure.DataStructureIterator()
EvenIterator
ds.