前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ArrayList的toArray()方法为啥不利用泛型返回List的泛型类型的数组探究

ArrayList的toArray()方法为啥不利用泛型返回List的泛型类型的数组探究

作者头像
明明如月学长
发布2021-08-31 14:37:27
1.6K0
发布2021-08-31 14:37:27
举报
文章被收录于专栏:明明如月的技术专栏

一、背景

有些同学提出“ArrayList的public T[] toArray(T[] a) 带参数的方法支持泛型可以返回参数类型的数组,public Object[] toArray()

方法为啥不利用泛型返回List的泛型类型的数组”?这个问题。

那让我们看下源码研究一下吧。另外我将介绍一下通用解决这类问题的方法,方便大家举一反三。

二、研究

无参源码java.util.ArrayList#toArray()

代码语言:javascript
复制
   public Object[] toArray() {
        return Arrays.copyOf(elementData, size);
    }

底层函数java.util.Arrays#copyOf(T[], int)

代码语言:javascript
复制
    @SuppressWarnings("unchecked")
    public static  T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

的确这里支持泛型。

但是我们看一下ArrayList真正存储对象的变量: transient Object[] elementData; 它的类型为Object数组。

因此从源码来看,返回值必然是Object数组了。

为啥不给转成E[] 这样呢?

一方面ArrayList真正存储对象的变量: transient Object[] elementData;

另外一方面创建ArrayList的时候,并不一定指定泛型类型的。

因此java.util.ArrayList#toArray()怎么搞?

代码语言:javascript
复制
  @Test
    public void test2() {
        ArrayList arrayList = new ArrayList();
        int random = RandomUtils.nextInt(3, MAX_LENGTH);
        log.debug("随机数-->{}", random);
        for (int i = 0; i < random; i++) {
            arrayList.add(i);
        }
        arrayList.add("String");

        Object[] objects = arrayList.toArray();
        log.debug("结果:{}", JSON.toJSONString(objects));

    }

总不能判断有泛型返回E[] 无泛型返回Object[]吧?

如果一个接口可能返回String,也可能返回Integer,那么返回值类型是不是应该定义为Object?

那么这个问题应该就明了。

三、类似的问题

正如前面说的:

(1)如果一个接口可能返回String,也可能返回Integer,那么返回值类型是不是应该定义为Object?

(2)这点又让我想到了fastjson的json反序列化时调用泛型的函数来转成对象。

com.alibaba.fastjson.JSON#parseObject(java.lang.String)

代码语言:javascript
复制
 public static JSONObject parseObject(String text) {
        Object obj = parse(text);
        if (obj instanceof JSONObject) {
            return (JSONObject)obj;
        } else {
            try {
                return (JSONObject)toJSON(obj);
            } catch (RuntimeException var3) {
                throw new JSONException("can not cast to JSONObject.", var3);
            }
        }
    }

然后带类型的com.alibaba.fastjson.JSON#parseObject(java.lang.String, java.lang.Class)

代码语言:javascript
复制
 public static  T parseObject(String text, Class clazz) {
        return parseObject(text, clazz);
    }

使用时:

一个是无类型参数,一个是有类型参数,有些类似。

四、怎么解决这类问题?

像这种问题还有很多很多,其实最关键的是勇于去扒源码,并结合其注释,再不行去找官方文档。

这三点可以解决绝大多数这类问题。

另外学习的时候多找共性,多类比学习,学的更快一些。

另外学习某个知识点最好自己本地多demo,这点可以参考《几个本地搭建练习项目来学习的小技巧分享》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/06/16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、背景
  • 二、研究
  • 三、类似的问题
  • 四、怎么解决这类问题?
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档