一、背景
有些同学提出“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