前段时间写bantouyan-json代码,偶然发现Java集合类的一个问题,就是一旦集合中出现了循环引用,调用hashCode方法就会触发StackOverflowError错误。一般情况下集合内不会出现循环引用,但Java集合并不禁止这样做,从具体应用上讲,循环引用的情况也有可能出现。但是,一旦直接或间接调用hashCode方法,就会导致StackOverflowError,我不清楚Java这样设计是一个失误还是这种情况没有必要处理,但它的存在会给代码设计带来一定的问题。
我当时的情况是想用HashSet存储一个ArraList对象,代码是这样写的:
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错误。
经检查,不光是List,其他集合对象,如Map、Set、Stack等也有这个问题,即他们的hashCode也是通过计算子元素的hashCode得到的。也就是说,无论是List,还是Map、Set,只要内部出现了循环引用,如一个List引用了一个Map,Map又引用了顶层的List,调用hashCode方法就会导致堆栈溢出错误。
这种错误出现的几率非常低,但存在这样的问题不能不说是Java集合设计的一个失误。既然应用中有可能出现集合间的循环引用,就应该避免这种错误出现。
分享到:
相关推荐
### Java集合类详解总结 在Java编程中,集合框架(Collection Framework)是处理一组对象的强大工具,它提供了标准的数据结构来存储和操作这些对象。Java集合框架主要包括`Collection`、`Set`、`List`、`Queue`、`...
Arrays和Collections是Java集合中的两个工具类。Arrays类包含用来操作数组的各种方法,如排序和搜索等。Collections类主要提供了在collection上进行操作的方法,如排序、查找等。 学习Java集合需要掌握以下几个方面...
### Java集合类原理详解 #### 1. 集合框架概述 集合框架是Java编程语言的核心组件之一,用于组织和操作数据集。它提供了一种灵活高效的方式来存储和访问对象集合,支持多种数据结构,如列表(List)、集(Set)、映射...
Java集合类详解 Java集合类是一个强大的工具,提供了多种方式来存储和操作数据。集合类可以分为两大类:List和Set。List是一个有序的集合,元素可以重复,而Set是一个无序的集合,元素不可重复。 List接口是Java...
Java集合类是Java编程语言中用于存储一组对象的容器,它们提供了比基本数组更灵活的存储和操作方式。集合类不包括传统的固定长度数组,而是提供了像List、Set和Map等接口以及它们的实现类,以适应不同场景的需求。 ...
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
### Java集合类总结 #### 一、概述 Java集合类框架是Java标准库的一个重要组成部分,主要用于存储和处理数据集合。这些集合类被定义在`java.util`包中,为开发者提供了灵活的数据结构来实现各种应用程序的需求。...
深入解析Java对象的equals()和hashCode()的使用 在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,就要设计另外一个。在多数情况下,这两个函数是不用考虑的,直接使用它们...
Java集合类是Java编程中非常重要的组成部分,它们提供了一种组织和管理数据的方式。Java集合框架主要由两个核心接口——`Collection`和`Map`构建。`Collection`接口又派生出三个子接口:`Set`、`List`和`Queue`。而`...
Java集合类是Java编程语言中不可或缺的一部分,它们用于存储、管理和操作对象。面试时,面试官经常通过提问关于集合类的问题来评估候选人的基础知识和实际经验。以下是一些常见的Java集合类面试题及其详细解答: 1....
在Java编程语言中,`hashCode()`和`equals()`方法是对象身份验证的关键组成部分,它们...这两个方法在Java编程中起着至关重要的作用,尤其是在处理集合类和数据结构时。了解并正确使用它们能够确保程序的正确性和效率。
Java工具类代码集合是Java开发中非常重要的组成部分,它们提供了许多通用的功能,使得开发者能够更加高效地编写代码,避免重复劳动。在这个集合中,我们通常会看到各种实用的方法,涵盖字符串处理、数组操作、日期...
通过对 hashCode 和 equals 方法的深入分析,我们可以更好地理解 Java 集合的实现原理和哈希表的工作机制。 一、hashCode 方法简介 hashCode 方法是 Java 中 Object 类的一个方法,用于返回对象的哈希码值。这个...
【Java Map 集合类简介】 在Java的`java.util`包中,集合类扮演着重要的角色,其中List和Map是最为常见的两种。List的实现例如ArrayList和Vector,它们都是可变大小的列表,适合存储和操作各种类型对象的序列。特别...
在Java中,Hashcode的约定是由Java.lang.Object类中的hashCode方法所规定的。这个方法规定了Hashcode的三个基本原则: 1. 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则...
Java集合排序及java集合类详解 Java集合框架是Java编程语言中极其重要的一部分,它提供了存储和操作数据的高效方式。本文将深入探讨Java集合框架的四大核心组件:`Collection`、`List`、`Map`和`Set`,以及它们的...
行排序的呢?这主要依赖于对象的自然排序或者定制排序。 在Java中,对于实现...在处理数据时,应根据实际需求选择合适的集合类型,同时注意对象的equals()和hashCode()方法的一致性,以确保集合操作的正确性。
Java集合类是Java编程语言中用于存储和管理对象的核心组件,位于`java.util`包中。集合类的主要优点在于它们的灵活性,能够适应各种数据结构需求,而不像数组那样需要预先知道存储对象的数量。集合类存放的是对象的...