最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

關(guān)于JAVA泛型數(shù)組類型擦除引發(fā)的問(wèn)題及解決方案

2023-03-10 18:12 作者:Cpp程序員  | 我要投稿

先看如下一個(gè)DEMO示例代碼:(其中doBatchGet被子類重寫(xiě)了1次)

public abstract class BaseDemoService<T> { ? ?public String batchGet(T... ints) { ? ? ? ?T one=ints[0]; ? ? ? ?System.out.println("one class:" + one.getClass().getCanonicalName()); ? ? ? ?return doBatchGet(one); ? ?} ? ?public String doBatchGet(T... ints){ ? ? ? ?System.out.println("com.example.springwebapp.service.Demo1Service.doBatchGet"); ? ? ? ?return String.join(",", Arrays.toString(ints)); ? ?} ? ? ? ?public String doGet(T one){ ? ? ? ?return one.toString(); ? ?} } ? ?@Servicepublic class Demo1Service extends BaseDemoService<Integer> { ? ?@Override ? ?public String doBatchGet(Integer... ints) { ? ? ? ?System.out.println("com.example.springwebapp.service.Demo1Service.doBatchGet"); ? ? ? ?return super.doBatchGet(ints); ? ?} ? ?@Override ? ?public String doGet(Integer one) { ? ? ? ?return super.doGet(one); ? ?} } ? ?

執(zhí)行單元測(cè)試,示例代碼如下:

? ?@Resource ? ?private BaseDemoService baseDemoService; ? ?@Test ? ?public void testOverride(){ ? ? ? ?Integer[] ints={1,2,3,4,5,6}; ? ? ? ?System.out.println("batchGet result:" + baseDemoService.batchGet(ints)); ? ?}

大家認(rèn)為最后batchGet result輸出的結(jié)果如何?有人可能會(huì)認(rèn)為這太簡(jiǎn)單了,就是1,但實(shí)際上的結(jié)果可能會(huì)讓你打臉,居然直接報(bào)錯(cuò),如下所示:

one class:java.lang.Integerjava.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer; at com.example.springwebapp.service.Demo1Service.doBatchGet(Demo1Service.java:5) at com.example.springwebapp.service.BaseDemoService.batchGet(BaseDemoService.java:11) at com.example.springwebapp.Springwebapp1ApplicationTests.testOverride(Springwebapp1ApplicationTests.java:38)... ...

報(bào)錯(cuò)的意思是類型轉(zhuǎn)換錯(cuò)誤,object數(shù)組類型不能轉(zhuǎn)換為integer數(shù)組類型,但我上面一行明明輸出的結(jié)果就是one class:java.lang.Integer,為何傳給doBatchGet就變成了object類型呢?是不是有點(diǎn)看不懂了,編譯也是正常的,但運(yùn)行就是報(bào)錯(cuò),如果把入?yún)⒌膇nts直接傳到doBatchGet方法入?yún)⒅幸彩荗K的,或者內(nèi)部將doBatchGet改為doGet,即使子類重寫(xiě)doGet一樣可以正確獲取結(jié)果 又或者doBatchGet沒(méi)有被子類重寫(xiě)也可以正確獲得結(jié)果,但如果單獨(dú)從ints中取一個(gè)成員然后再調(diào)doBatchGet方法就會(huì)報(bào)錯(cuò),大家知道為啥嗎?

我這里就不賣關(guān)子了,其實(shí)就是泛型參數(shù)類型擦除“惹的禍”,因?yàn)閯e看我們是BaseDemoService,其實(shí)這個(gè)T在編譯后就是一個(gè)Object,在從ints取出一個(gè)成員值one后,雖然指明是T,但實(shí)際就是Object,最后在調(diào)doBatchGet的時(shí)候,JVM會(huì)將one這個(gè)變量隱式轉(zhuǎn)換為one的Object數(shù)組,然后調(diào)doBatchGet,由于doBatchGet方法被子類重寫(xiě),而重寫(xiě)后入?yún)⑹蔷唧w的類型(Integer數(shù)組),這樣就導(dǎo)致了上面的object數(shù)組類型不能轉(zhuǎn)換為integer數(shù)組類型的錯(cuò)誤。

當(dāng)我們知道了問(wèn)題原因后,那么就可以對(duì)癥下藥了.

解法一(關(guān)鍵點(diǎn):通過(guò)反射創(chuàng)建一個(gè)入?yún)⒄鎸?shí)類型的數(shù)組,這個(gè)數(shù)組與doBatchGet入?yún)㈩愋鸵恢?:

? ?public String batchGet(T... ints) { ? ? ? ?T[] arr = (T[]) Array.newInstance(ints[0].getClass(), 1); ? ? ? ?arr[0]=ints[0]; ? ? ? ?System.out.println("arr class:" + arr.getClass().getCanonicalName()); ? ? ? ?return doBatchGet(arr); ? ?}

解法二(關(guān)鍵點(diǎn):將doBatchGet由原來(lái)的可變參數(shù)直接改為L(zhǎng)ist,這樣即使子類重寫(xiě),因?yàn)長(zhǎng)ist本身就是泛型,所以擦除了就都是一樣的):

? ?public String batchGet(T... ints) { ? ? ? ?return doBatchGet(Arrays.asList(ints)); ? ?}public String doBatchGet(List<T> ints){ ? ? ? ?System.out.println("com.example.springwebapp.service.Demo1Service.doBatchGet"); ? ? ? ?return ints.toString(); ? ?}

以上就是實(shí)際項(xiàng)目中碰到的問(wèn)題及解法,希望對(duì)大家也有幫助。


關(guān)于JAVA泛型數(shù)組類型擦除引發(fā)的問(wèn)題及解決方案的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
万全县| 南京市| 桓台县| 上虞市| 平邑县| 任丘市| 永靖县| 逊克县| 芜湖市| 同江市| 呼和浩特市| 老河口市| 荆门市| 上蔡县| 桓台县| 清涧县| 乳山市| 锡林浩特市| 西华县| 昌都县| 玉林市| 濉溪县| 石嘴山市| 深水埗区| 车致| 通道| 华亭县| 南木林县| 新密市| 山西省| 松桃| 定边县| 苏州市| 罗平县| 林口县| 工布江达县| 台南县| 荥经县| 凤山市| 贵德县| 沈丘县|