- ArrayList<Object> list = new ArrayList<Object>();
- list.add(list);
- HashSet<Object> set = new HashSet<Object>();
- set.add(list);
- //Exception in thread "main" java.lang.StackOverflowError
- // at java.util.AbstractList$Itr.next(AbstractList.java:345)
- // at java.util.AbstractList.hashCode(AbstractList.java:526)
- // at java.util.AbstractList.hashCode(AbstractList.java:527)
结果测试时就冒出了StackOverflowError错误,是因为间接调用AbstractList的hashCode方法引发的。查看Java的API文档,AbstractList的hashCode是把每个子元素的hashCode通过迭代计算获得的,也就是说,要计算AbstractList的hashCode,就要把每个子元素的hashCode先计算一遍,若是这些子元素中的某一个或子元素的子元素引用到上级对象,那么hashCode方法就会出现无限递归调用,最终出现StackOverflowError错误。java
经检查,不光是List,其余集合对象,如Map、Set、Stack等也有这个问题,即他们的hashCode也是经过计算子元素的hashCode获得的。也就是说,不管是List,仍是Map、Set,只要内部出现了循环引用,如一个List引用了一个Map,Map又引用了顶层的List,调用hashCode方法就会致使堆栈溢出错误测试
public static void main(String[] args) {
Map map = new HashMap();
map.put(map, map);
map.put(map, map);
}spa
Exception in thread "main" java.lang.StackOverflowError
at java.util.Objects.hashCode(Objects.java:98)
at java.util.HashMap$Node.hashCode(HashMap.java:296)
at java.util.AbstractMap.hashCode(AbstractMap.java:507)
at java.util.Objects.hashCode(Objects.java:98)
at java.util.HashMap$Node.hashCode(HashMap.java:296)
at java.util.AbstractMap.hashCode(AbstractMap.java:507)
at java.util.Objects.hashCode(Objects.java:98)
at java.util.HashMap$Node.hashCode(HashMap.java:296)
at java.util.AbstractMap.hashCode(AbstractMap.java:507)对象