前言
这是我在抖音二面的时候自我感觉没有答好的一题。因为我的中心只是围绕在了
T
被
Object
替换的问题上了,并没有去讲解他会带来的问题。
创新互联制作网站网页找三站合一网站制作公司,专注于网页设计,网站设计制作、成都网站建设,网站设计,企业网站搭建,网站开发,建网站业务,680元做网站,已为近1000家服务,创新互联网站建设将一如既往的为我们的客户提供最优质的网站建设、网络营销推广服务!
思维导图
什么是泛型擦除?
其实我们很常见这个问题,你甚至经常用,只是没有去注意罢了,但是很不碰巧这样的问题就容易被面试官抓住。下面先来看一段代码吧。
List list = new ArrayList(); List listString = new ArrayList(); List listInteger = new ArrayList();
这几段代码简单、粗暴、又带有很浓厚的熟悉感是吧。那我接下来要把一个
数字1
插入到这三段不一样的代码中了。
作为读者的你可能现在已经黑人问号了????你肯定有很多疑问,这明显不一样啊,怎么可能。
public class Main { public static void main(String[] args) { List list = new ArrayList(); List listString = new ArrayList(); List listInteger = new ArrayList(); try { list.getClass().getMethod("add", Object.class).invoke(list, 1);
listString.getClass().getMethod("add", Object.class).invoke(listString, 1); // 给不服气的读者们的测试之处,你可以改成字符串来尝试。
listInteger.getClass().getMethod("add", Object.class).invoke(listInteger, 1);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("list size:" + list.size());
System.out.println("listString size:" + listString.size());
System.out.println("listInteger size:" + listInteger.size());
}
}
不好意思,有图有真相,我就是插进去了,要是你还不信,我还真没办法了。
探索真相
上述的就是泛型擦除的一种表现了,但是为了更好的理解,当然要更深入了是吧。虽然
List
很大,但却也不是不能看看。
两个关键点,来验证一下:
- 数据存储类型
- 数据获取
// 先来看看画了一个大饼的List
// 能够过很清楚的看到泛型E
public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable{
// 第一个关键点
// 还没开始就出问题的存储类型
// 难道不应该也是一个泛型E?
transient Object[] elementData; public E get(int index) {
rangeCheck(index); return elementData(index); // 1---->
} // 由1直接调用的函数
// 第二个关键点,强制转化得来的数据
E elementData(int index) { return (E) elementData[index];
}
}
我想,其实你也能够懂了,这个所谓的泛型
T
最后会被转化为一个
Object
,最后又通过强制转化来进行一个转变。从这里我们也就能够知道为什么我们的数据从前面过来的时候,
String
类型数据能够直接被
Integer
进行接收了。
带来什么样的问题?
(1) 强制类型转化
这个问题的结果我们已经在上述文章中提及到了,通过反射的方式去进行插入的时候,我们的数据就会发生错误。
如果我们在一个
List
中在不知情的情况下插入了一个
String
类型的数值,那这种重大错误,我们该找谁去说呢。
(2)引用传递问题
上面的问题中,我们已经说过了
T
将在后期被转义成
Object
,那我们对引用也进行一个转化,是否行得通呢?
List listObject = new ArrayList