先po上代码
import java.util.*;
public class CountingIntegerList extends AbstractList<Integer> {
private int size;
public CountingIntegerList(int size) {
this.size = size < 0 ? 0 : size;
}
public Integer get(int index) {
return Integer.valueOf(index);
}
public int size() {
return size;
}
public static void main(String[] args) {
System.out.println(new CountingIntegerList(30));
}
} /* Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
*///:~
它的输出居然是[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]。
开debug模式逐语句分析下
发现程序多次使用get()和size()方法 ,跳进去看看。
,
看到AbstractList的内部类Itr的hasNext()使用了size(),next()使用了get(),基本就能猜到了。下面是这段代码的解析。
public static void main(String[] args) {
System.out.println(new CountingIntegerList(30));
}
System.out.println()会调用CountingIntegerList的toString()方法。那就看看它父类的toString()吧。在它父类的父类AbstractCollection找到了toString()的实现。
/**
* Returns a string representation of this collection. The string
* representation consists of a list of the collection's elements in the
* order they are returned by its iterator, enclosed in square brackets
* (<tt>"[]"</tt>). Adjacent elements are separated by the characters
* <tt>", "</tt> (comma and space). Elements are converted to strings as
* by {@link String#valueOf(Object)}.
*
* @return a string representation of this collection
*/
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
看到E e = it.next()这一行,打个断点进去看next()的实现(ctrl+左键是看不到的)
public E next() {
checkForComodification();
try {
int i = cursor;
E next = get(i);
lastRet = i;
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
再看到E next = get(i),没错,它调用的是我们重载的get()不断地返回Integer。那为什么返回的上限是29呢。我们回头看toString()中if (! it.hasNext())这行,进入hasNext()方法
public boolean hasNext() {
return cursor != size();
}
再进入size(),发现这是我们重载的size(),它返回的是30,所以打印数字的范围是0到29。