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

相关文章
|
2月前
|
Java 开发者
使用HashMap的values()方法返回的值转换为List时遇到错误
使用HashMap的values()方法返回的值转换为List时遇到错误
|
2月前
|
存储 缓存 NoSQL
利用Redis List实现数据库分页快速查询的有效方法
利用Redis List实现数据库分页快速查询的有效方法
|
5天前
如何实现数组和 List 之间的转换?
如何实现数组和 List 之间的转换?
|
4月前
|
Java 程序员
Java集合框架:List、Set、Map类型及泛型详解
Java集合框架:List、Set、Map类型及泛型详解
|
5天前
|
Java API
【亮剑】Java的List,如何删除重复的元素,教你三个方法搞定!
【4月更文挑战第30天】本文介绍了三种Java中删除List重复元素的方法:1) 使用HashSet,借助其不允许重复值的特性;2) 利用Java 8 Stream API的distinct()方法;3) 对自定义对象重写equals()和hashCode()。每种方法都附带了代码示例,帮助理解和应用。
|
1月前
List中的remove方法遇到报错不能删除以及四种解决办法点赞收藏
List中的remove方法遇到报错不能删除以及四种解决办法点赞收藏
18 0
|
2月前
使用List中的remove方法遇到数组越界
使用List中的remove方法遇到数组越界
17 2
|
2月前
|
Java
JAVA——List中剔除空元素(null)的三种方法汇总
JAVA——List中剔除空元素(null)的三种方法汇总
|
3月前
|
存储 Java 索引
java list集合相关介绍和方法使用操作
java list集合相关介绍和方法使用操作
30 1
|
3月前
|
Java
java List数组根据给定大小分割数组
在获取到很长的数组时,一次性处理数据量太大,需要分批处理,这就需要分批处理了。 1、使用List的subList,封装方法 2、google工具类型Lists的partition 经测试个人推荐使用第一种方法,效率上快了10几倍,估计是因为没有重新生成数组的原因
47 8