在浏览Effective Java示例时,我无法理解下面的代码。 这个匿名抽象类如何在不迭代数组元素或调用add()方法的情况下返回对象列表。
以下代码在幕后发生了什么?
public static void main(String[] args) {
int a[] = new int[10];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
List<Integer> list = intArrayAsList(a);
System.out.println(list);
}
static List<Integer> intArrayAsList(final int[] a) {
if (a == null) {
throw new NullPointerException();
}
return new AbstractList<Integer>() {
@Override
public Integer get(int index) {
return a[index];
}
@Override
public int size() {
return a.length;
}
@Override
public Integer set(int index, Integer element) {
int oldVal = a[index];
a[index] = element;
return oldVal;
}
};
}
答案 0 :(得分:1)
new AbstractList<Integer>() { ... }
不是抽象类。它是抽象类型AbstractList<Integer>
的子类。该特定类型仅使用两种抽象方法实现几乎所有List<Integer>
方法:get
和set
(某些操作也需要size
),其实现由你的榜样。
特别是,不需要调用add
方法,因为提供的实现是一个包装提供的int[]
的闭包。 AbstractList
的{{1}}实施将在内部委托给iterator()
提供的实施。
答案 1 :(得分:1)
未调用 add 的原因是因为它从未创建新列表。新的 AbstractList 只是持有对数组'a'的引用,当你遍历新的AbstractList时,它只会在数组中查找。
为了好玩,请尝试从该行中删除关键字“final”:
static List<Integer> intArrayAsList(final int[] a) {
它将不再编译。原因是因为AbstractList是一个匿名类,为了能够使用变量,该变量需要是最终的。