ArrayList源码之6260652 bug号

ArrayList 源码深度解析 ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object数组,以达到可以动态增长和缩减的索引序列。 长啥样? 如图,是一个长度为6,存储了6个6的数组,下标(index)从0开始,数组(elementData)表示存储的数据本身。 有哪些基本概念? index 表示数组下标;... 阅读详情

ArrayList源码之6260652 bug号

List的toArray()方法有多个实现,主要关注两个。原因是分析ArrayList源码时,解决构造方法中的“c.toArray might (incorrectly) not return Object[] (see 6260652)”注释。

ArrayList的构造方法源码

public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

源码中为何有“if (elementData.getClass() != Object[].class)”判断呢?
因为elementData = c.toArray();有两种类型的返回,一个是Object[] 类型,一个是具体的数组类型(如Integer[])。

  • 如果c.toArray()返回的类型是Object[]时,则不需要转换,直接使用(因为源码中transient Object[]
    elementData就是存List数据的数组,类型符合要求);
  • 如果c.toArray()返回的类型是Intger[]时,则需要转化为Object[]类型;

验证c.toArray()方法会返回两种类型的数组这一现象

测试代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestMain {
    public static void main(String[] args) {
        testBug6260652();
//        testBug6260652GZ();
        //      testBug6260652GZ2();
    }

    /**
     * 测试toArray方法返回类型
     * c.toArray might (incorrectly) not return Object[] (see 6260652)
     */
    private static void testBug6260652(){
        Integer[] array={1,2};
        //通过Arrays.asList转换,保留了原来的基本类型
        List list= Arrays.asList(array);
        //转换后的数组
        Object[] array3=list.toArray();
        System.out.println("转换后的数组:"+array3.getClass());
        System.out.println(array3.getClass()==Object[].class);
        List<Integer> newList=new ArrayList<Integer>();
        newList.add(4);
        System.out.println("new ArrayList 转换后数组类型:"+newList.toArray());
        System.out.println(newList.toArray().getClass()==Object[].class);
    }
}

测试方法打印结果
转换后的数组:class [Ljava.lang.Integer;
false
new ArrayList 转换后数组类型:[Ljava.lang.Object;@71bc1ae4
true
总结现象

通过下面的代码,toArray方法返回的是Integer[]

 		Integer[] array={1,2};
        //通过Arrays.asList转换,保留了原来的基本类型
        List list= Arrays.asList(array);
        //转换后的数组
        Object[] array3=list.toArray();

通过下面的代码,toArray方法返回的是Object[]

在这里插入代码片List<Integer> newList=new ArrayList<Integer>();
        newList.add(4);
        System.out.println("new ArrayList 转换后数组类型:"+newList.toArray());
        System.out.println(newList.toArray().getClass()==Object[].class);

综上所述,toArray方法确实会返回两种类型的数组,也就理解了ArrayList源码中为何有“c.toArray might (incorrectly) not return Object[] (see 6260652)”这段注释以及下面的判断逻辑。

结合ArrayList源码分析

总结上面的测试方法,已经可以确定toArray方法返回两种类型的数组。那么结合ArrayList源码继续分析,构造方法中“c.toArray might (incorrectly) not return Object[] (see 6260652)”这段注释的原因。

测试代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TestMain {
    public static void main(String[] args) {
//        testBug6260652();
        testBug6260652GZ();
        testBug6260652GZ2();
    }

    /**
     * toArray方法返回Integer[]数组,测试构造方法
     */
    private static void testBug6260652GZ(){
        Integer[] array={1,2};
        //通过Arrays.asList转换,保留了原来的基本类型
        List list= Arrays.asList(array);
        List list2 =new ArrayList<>(list);
        System.out.println(list);
        System.out.println(list2);
    }
    /**
     * toArray方法返回Object[]数组,测试构造方法
     */
    private static void testBug6260652GZ2(){
        List<Integer> newList=new ArrayList<Integer>();
        newList.add(4);
        List list2 =new ArrayList<>(newList);
        System.out.println(newList);
        System.out.println(list2);
    }
}

调试main方法进行分析

testBug6260652GZ方法中进入ArrayList构造方法时,elementData的类型是Integer[],if (elementData.getClass() != Object[].class)这个判断为true。

public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();//返回的是Integer[]
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
            	//走这段逻辑
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

testBug6260652GZ2方法中进入ArrayList构造方法时,elementData的类型是Object[],if (elementData.getClass() != Object[].class)这个判断为false。

在这里插入代码片public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();//返回的是Object[]
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
            	//不走下面的逻辑
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

综上所述,构造方法中“c.toArray might (incorrectly) not return Object[] (see 6260652)”这段注释的原因是elementData = c.toArray()返回的类型可能是Object[],也可能是具体的数组类型,如Integer[]。

为何toArray会返回两种数组类型呢?

依旧用上述测试代码进行调试,跟踪 elementData = c.toArray()中toArray方法的实现。
当从testBug6260652GZ方法入口进入构造时,断点如下图:
在这里插入图片描述

当从testBug6260652GZ2方法入口进入构造时,断点如下图:
在这里插入图片描述
结合上面两张图可以看到,两个方法分别进入两个实现:

  • Object[] Arrays$ArrayList.toArray() :Arrays的内部类ArrayList的方法
  • Object[] ArrayList.toArray():java.util.ArrayList的方法

为何会出现两个实现呢?
因为List list= Arrays.asList(array);返回的是Arrays.ArrayList,而 List newList=new ArrayList();返回的是java.util.ArrayList

JDK1.6集合框架bug 6260652解析 主要为大家解析了JDK1.6集合框架bug:c.toArray might (incorrectly) not return Object[] (see 6260652),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 立即下载

相关推荐

vscode+keil嵌入式软件开发全流程

vscode+keil嵌入式软件开发全流程

AspringQ的博客 6780

ArrayList c.toArray might (incorrectly) not return Object[] (see 6260652)

arraylist

qq_34412985的博客 609

ArrayList源码中c.toArray might (incorrectly) not return Object[] (see 6260652)

Java Jdk 1.8 ArrayList源码中有下面代码: public ArrayList(Collection c) { elementData = c.toArray(); size = elementData.length; // c.toArray might (incorrectly) not return Object[] (

Dream It Possible 2185

基于STM32的工业设备状态监测系统

工业设备的预测性维护需求日益增长,本文设计了一款基于STM32的智能监测终端,可实时采集设备振动、温度、电流等关键参数,通过边缘计算分析设备健康状态,实现故障预警与能效优化。系统支持4G/LoRa远程通信,适用于工厂、发电站等工业场景。本系统实现了工业设备关键参数的实时监测,故障识别准确率达到92%。:STM32F429(带FPU,支持浮点运算)多参数联合判据(振动+温度+电流突变检测)ACS712电流检测模块(0-30A)FFT频谱分析(识别轴承故障特征频率)故障代码生成(支持16种预设故障类型)

stm32d1219的博客 1321

思科路由器重分发(静态路由+OSPF动态路由+RIP动态路由)

思科路由器重分发(静态路由+OSPF动态路由+RIP动态路由)

2301_81256766的博客 1257

Java笔记---c.toArray might (incorrectly) not return Object[] (see 6260652)官方Bug

一、前言 在分析ArrayList源码是,看到toArray()有这么一句:c.toArray might (incorrectly) not return Object[] (see 6260652)。网上百度一下,原来,这是一个官方bug。经过本人分析,说的就是public Object[] toArray() 返回的类型不一定就是 Object[],其类型取决于其返回的实际类型. 二...

GuLu_GuLu_jp的专栏 5447

基于结构的虚拟筛选模型 gnina 从源码编译

所需要的软件安装包: 安装 CUDA 装的时候看着点,第二个要你装驱动的选择,回答N,不装。 sudo sh cuda_10.0.130_410.48_linux.run sudo vim ~/.bashrc 在 ~/.bashrc 文件最后加上 export PATH=/usr/bin:/usr/local/cuda-10.0/bin${PATH} export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:${LD_LIBRARY_PATH} source ~

周迪新的博客 3187

ArrayList 有参构造函数中的c.toArray might (incorrectly) not return Object[] (see 6260652)问题理解

问题: 在走读ArrayList参数为Collection类型的有参构造函数时,发现构造函数把参数转换成数组并赋值给成员变量elementData后,又进行了elementData.getClass() != Object[].class判断,并在条件为true的时候又进行了一次转换,并在该处说明c.toArray might (incorrectly) not return Object[] (see 6260652),具体代码如下: public ArrayList(Collect...

lcgskycby的博客 385

以太网以及车载以太网概述

千兆网线和百兆网线区别 1、所谓的百兆网线其实就是 五类线 和超五类线 ,而千兆网线主要是指六类线 和超六类线 ,另外还有古老的十兆网线也就是指 四类线 和 三类线 等。 2、在使用上,其实千兆网线和百兆网线是没什么区别的,千兆网线完全兼容百兆网络。 3、百兆网线的线芯是8芯,但上传和下载只用到了其中的4根,而千兆网线需要完全用到8根。 4、另外在线芯的排布上,千兆网线的线芯中间有个十字形的塑料架,用来把四组8芯的线分开,这个百兆网线是没有的, 5、所有的网线在外皮上都有种类标识,CAT5 CAT

$好记性还是要多记录$ 4074

matlab处理las点云(1)——las/laz格式解析【2024最新版】

matlab中的las/laz格式解析。博客长期更新,本文最近一次更新时间为:2024年11月9日。

点云侠的博客 8460

一份文档可以助你涨薪10K,你信吗?我信了,你精通,你也可以

靠这份文档,跳槽涨薪10K 去年,也就是2019年,有一个朋友,整天缠着我跟我要面试题,这位仁兄,属于那种佛系生活,耐心极高(软磨硬泡)的,真的是给我磨得没有任何的办法了,正好,从网上找到一份面试文档,然后我就顺手给了他,没想到,几个月之后,就在疫情刚刚好转的时候,他突然要请我吃饭,还要亲自下厨,我一脸懵的去了,然后他跟我说,他除了自己的技术之外,面试的时候,好多知识点问的都是我给他的文档...

Java架构师联盟 298

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

ArrayList源码解析之初始化

在上一篇《ArrayList源码解析之架构》里面,对ArrayList的整体架构和数组的相关知识做了分享,本节将延续上节知识点,对ArrayList的源码进行分析。 1. ArrayList初始化方式 在开始介绍初始化之前,首先需要注意在源码中有两个空引用,如下图: EMPTY_ELEMENTDATA是一个共享空数组实例,当传入ArrayList构造器的容量为0时,用这个数组表示容器...

I_LV_XJ的博客 766

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

银行系科技子公司Java面试复盘:HashMap、ConcurrentHashMap与数据库高频追问

Java集合框架与数据库索引是后端开发面试的核心基础。HashMap通过数组加链表加红黑树实现高效查找,其扩容机制与线程安全问题常被深入追问;ConcurrentHashMap在JDK 1.8中采用CAS加synchronized细化锁粒度,显著提升并发性能。数据库方面,B+树索引结构与最左前缀原则直接影响SQL执行效率,事务隔离级别与MVCC机制则是保障数据一致性的关键。掌握这些原理,不仅能应对面试中的层层追问,更能提升工程实践中的问题排查与优化能力。本文复盘银行系科技子公司面试实战,涵盖Java基础、数

weixin_34200628的博客 201

CopyOnWriteArrayList源码阅读-- java bug 6260652

简单的说,就是代码里用到的Collection.toArray方法返回的结果预期是Object[],但有Collection的子类在实现此方法的时候返回的结果并不是Object[]。这个类就是Arrays.ArrayList,其代码如下,它的toArray方法是使用的clone,返回的真实类型其实是E[]如果直接拿到这个数组使用,往里放入非E类型的其他Object,就会出现异常。jdk的bug都记录在了自己的数据库中,可以在网站上用bugid查询。可以直接看jdk bug网站上的介绍,

lijianqingfeng的专栏 517

学习 JAVA 源码笔记之 ArrayList 笔记 # c.toArray()

在 学习 JAVA ArrayList 源码时,看到 ArrayList 带参数的构造方法中有 c.toArray might (incorrectly) not return Object[] (see 6260652) 一句这样的注释,不明白什么意思所以深入看了一下,原来是 Java 中的一个 BUG https://bugs.java.com/bugdatabase/view_bu...

生于忧患、死于安乐。的博客 389

JDK漏洞之6260652

看过JDK源码的童鞋可能会发现ArrayList和CopyOnWriteArrayList类中有如下源码注释: . 这个see 6260652是个什么玩意呢?它其实是JDK的bug文档编号。 https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6260652 这是个什么bug呢? 假如有一个Object[]数组,并不代表可以将Ob...

gzheclipse的博客 1115

你连存活到JDK8中著名的Bug都不知道,我怎么敢给你加薪

CopyOnWriteArrayList.java和ArrayList.java,这2个类的构造函数,注释中有一句话 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public ArrayList(Collection<? ...

JavaEdge全是干货的技术号 5万+

ArrayList 源码

ArrayList 源码 ArrayList概览 基本概念 ArrayList 的结构较为简单,就是一个数组。结构如下图所示。ArrayList中有一些重要概念、属性: index:当前下标 elementData:数组,该数组的大小,经常与 ArrayList 的size 混淆,需要注意。 DEFAULT_CAPACITY:数组的初始大小,默认是 10 size 表示当前ArrayList实际有多少个数据,没有使用 volatile 修饰; modCount :当前数组的版本号,数组结构有变动,就会

lik_lik的博客 4309

java集合系列08番外篇 ArrayList(Collection c)构造器中的bug介绍

ArrayList构造器中有这样一段代码:public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not re

weixin_36210698的博客 819

java问题序号_Java Bug--官方编号为 6260652

在看ArrayList源码时,发现了这样一行代码c.toArray might (incorrectly) not return Object[] (see 6260652)意思是c.toArray()不一定会返回 Object[] ,请查看编号为6260652的Java Bug这里附上Java Bug 网址: Java Bug Database,可以根据关键词或bug id 查询详细信息看一组实...

weixin_35474374的博客 304

利用Jdk 6260652 Bug解析Arrays.asList

在java.util.ArrayList源码中: c.toArray might (incorrectly) not return Object[] (see 6260652) 产生疑惑: 附上Java Bug 网址: Java Bug Database ,可以根据关键词或bug id 查询详细信息这个Bug的描述中可以看出:原因:Arrays内部实现的ArrayList的toArray()...

weixin_30938149的博客 319

ArrayList 6260652

JDK1.6集合框架bug:c.toArray might (incorrectly) not return Object[] (see 6260652) 最近在看JDK的源码:CopyOnWriteArrayList.java和ArrayList.java,这2个类的构造函数,注释中有一句话看不懂。 public ArrayList(Collection c) { element

Mo.Se7en 337

由ArrayList构造函数源码引出的问题

由ArrayList构造函数源码引出的问题   ArrayList应该用得很多了。最近看了看其源码,发现有很多细节,如果要我们自己来实现,估计会考虑不到。当然,这些细节跟jdk本身一些实现的bug有关,如果不去深挖,定然是不能发现。本文从ArrayList的一个构造函数开始剖析。   该构造函数源代码如下: 1 public ArrayList(Collectionextends

evilcry2012的专栏 332

你连存活到JDK8中著名的Bug都不知道,我怎么敢给你加薪?

1、有自己的规划,给自己制定一个学习时间,在什么时间学完什么东西,可以以跳槽作为学习目标和检测学习结果的实践.2、有相应的学习架构,现在很多的人感觉都在学习,但是学的知识比较小众或者在市面上已经接近被淘汰,这样的学习基本都是浪费时间3、贪多不烂,最好有精准的学习,这个时候,有一个老师傅带你,他的经验会帮你节省很多时间,也可以帮你少走很多弯路。...

m0_72134256的博客 118
上一篇: Java 1.8 RandomAccess接口
下一篇: 计算机的原码、反码、补码
ludkjava
博客等级 码龄11年 173粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值