新聞中心
泛型信息只存在于代碼編譯階段,但是在java的運(yùn)行期(已經(jīng)生成字節(jié)碼文件后)與泛型相關(guān)的信息會被擦除掉,專業(yè)術(shù)語叫做類型擦除。

今天我們來講解泛型中另一個(gè)重要知識點(diǎn)——泛型擦除!
十分鐘理解Java泛型擦除十分鐘理解Java泛型擦除
泛型擦除概念
泛型信息只存在于代碼編譯階段,但是在java的運(yùn)行期(已經(jīng)生成字節(jié)碼文件后)與泛型相關(guān)的信息會被擦除掉,專業(yè)術(shù)語叫做類型擦除。我們來看一個(gè)例子:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
System.out.println(l1.getClass()==l2.getClass());
運(yùn)行代碼,結(jié)果為True
這是因?yàn)锳rrayList 和ArrayList 在 jvm 中的 Class 都是 List.class,二者在 jvm 中等同于List
利用類型擦除干“壞事兒”
大家都知道,下面這段代碼l.add(123)無法編譯通過,因?yàn)?23不是String類型,這也是使用泛型的好處之一。
ArrayList l=new ArrayList();
l.add("abc");
l.add(123);
但是我們理解了泛型擦除的原理,我們可以巧妙地利用這個(gè)原理結(jié)合反射知識干一些“壞事”,例如:
ArrayListl=new ArrayList();
l.add("abc");
try {
Method method = l.getClass().getDeclaredMethod("add",Object.class);
method.invoke(l,"test");
method.invoke(l,100.f);
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("list的大小是:"+l.size());
for ( Object o: l){
System.out.println(o);
}
運(yùn)行結(jié)果是:
list的大小是:3
abc
test
100.0(被成功插入到ArrayList中)
我們可以看見100.0 成功地插入到ArrayList 中了,所以利用類型擦除的原理并結(jié)合反射的手段就繞過了正常開發(fā)中編譯器不允許的操作限制。
通俗的理解
我們可以將泛型比作是一個(gè)看守,他來守護(hù)我們的代碼安全,然后設(shè)置各項(xiàng)規(guī)定,“xxx 禁止出入”的提醒。而現(xiàn)實(shí)生活中,也總會有些人能夠基于對門衛(wèi)們生活作息的規(guī)律,繞開他們的監(jiān)視(反射結(jié)合泛型擦除)來干一些壞事兒 。
分享題目:詳解Java泛型擦除
分享URL:http://m.fisionsoft.com.cn/article/cceccce.html


咨詢
建站咨詢
