ArrayList的toArray()方法为啥不利用泛型返回List的泛型类型的数组探究-阿里云开发者社区

开发者社区> 明明如月> 正文

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

简介: ArrayList的toArray()方法为啥不利用泛型返回List的泛型类型的数组探究
+关注继续查看

一、背景

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


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


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



二、研究

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


  public Object[] toArray() {

       return Arrays.copyOf(elementData, size);

   }

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


   @SuppressWarnings("unchecked")

   public static <T> 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()怎么搞?


 @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)


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<T>)


public static <T> T parseObject(String text, Class<T> clazz) {

       return parseObject(text, clazz);

   }

使用时:




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



四、怎么解决这类问题?

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


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


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


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



创作不易,如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。


另外欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。


https://t.zsxq.com/Z3bAiea  申请时标注来自CSDN。


 

————————————————

版权声明:本文为CSDN博主「明明如月学长」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/w605283073/article/details/92251503

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Elasticsearch-doc基本操作
document是es中比较重要的一个概念,相当于数据库中的行数据,es可以对document进行操作,主要包括新增doc、删除doc、更新doc、更新doc的某个部分等。
12 0
案例_点菜| 学习笔记
快速学习案例_点菜
13 0
案例分享——华媒传播|学习笔记
快速学习 案例分享——华媒传播
6 0
为什么 MySQL 不推荐默认值为 null ?
通常能听到的答案是使用了NULL值的列将会使索引失效,但是如果实际测试过一下,你就知道IS NULL会使用索引,所以上述说法有漏洞。
7 0
案例分享——趣拍|学习笔记
快速学习 案例分享——趣拍
15 0
ssm 整合| 学习笔记
快速学习 ssm 整合
14 0
阿里云智能制造解决方案:从中国制造到中国智造|学习笔记
快速学习 阿里云智能制造解决方案:从中国制造到中国智造
9 0
案例分享——钉钉|学习笔记
快速学习 案例分享——钉钉
10 0
首长,Redis 性能优化十三条军规立好了,请过目~
Redis作为高性能的内存数据库,在大数据量的情况下也会遇到性能瓶颈,日常开发中只有时刻谨记优化铁则,才能使得Redis性能发挥到极致。 本文将会介绍十三条性能优化军规,开发过程中只要按照执行,性能必能质的飞跃。
4 0
Spring 整合 mybatis04| 学习笔记
快速学习 Spring 整合 mybatis04
9 0
+关注
明明如月
阿里巴巴 资深Java开发工程师
343
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载