在学习自我参照收集的过程中,我想出了投掷的地方 堆栈溢出错误。
请在下面找到源代码。
import java.util.*;
public class TestSelfColl {
public static void main(final String[] args) {
test(new ArrayList<Collection<?>>());
test(new LinkedList<Collection<?>>());
test(new HashSet<Collection<?>>());
test(new LinkedHashSet<Collection<?>>());
}
private static void test(final Collection<Collection<?>> collection) {
collection.add(collection);
System.out.println(collection);
try {
System.out.println(collection.hashCode());
} catch (final StackOverflowError err) {
System.out.println(err + " for " + collection.getClass());
}
}
}
真的想知道为什么会出现这个错误。
我的期望是我将输出为:
[(此收藏)]
123
...
但相反,我得到了......
[(此收藏)]
java.util.ArrayList类的java.lang.StackOverflowError
...
答案 0 :(得分:1)
AbstractCollection
不会发生这种情况,因为该类不会覆盖Object
的{{1}}。
但是,如果您添加hashCode
作为自身成员,ArrayList
的{{1}}会遇到无限递归,因为ArrayList
的{{1}} (在hashCode
中实现)是其元素'hashCodes:
ArrayList
hashCode
不会导致相同的无限递归的原因是此检查(在AbstractList
中,public int hashCode() {
int hashCode = 1;
for (E e : this)
hashCode = 31*hashCode + (e==null ? 0 : e.hashCode()); // e.hashCode() is a self call in your example
return hashCode;
}
未覆盖):
toString
答案 1 :(得分:0)
AbstractCollection.toString()有一个简单的检查来停止包含自己的集合的递归。
将相同的检查添加到AbstractSet.hashCode()和AbstractList.hashCode()将解决它