最近一個(gè)朋友做猜數(shù)字游戲的解法,我也嘗試了一下,在做數(shù)據(jù)生成器的時(shí)候,就希望做一個(gè)類(lèi)型無(wú)關(guān)的,其實(shí)這個(gè)問(wèn)題在去迅雷面試的時(shí)候就被問(wèn)到,不過(guò)當(dāng)時(shí)想都沒(méi)想就放棄了,雖然面試當(dāng)天回來(lái)的時(shí)候,完成了一下,但結(jié)果還是差強(qiáng)人意。所以想借這個(gè)機(jī)會(huì)弄一下。
在記錄一條數(shù)據(jù)(Record)的時(shí)候,我本來(lái)使用了 List 實(shí)例化成 ArrayList,然后開(kāi)始算,不過(guò)借助 JProbe 看了一下,List.size() 和 List.get(i) 這兩個(gè)方法因?yàn)檎{(diào)用次數(shù)太多而占用了大部分的時(shí)間,所以第一想法是改成數(shù)組。
當(dāng)我 new Record 的時(shí)候,使用的是 list ,自然想把這個(gè) List<T> 轉(zhuǎn)換成數(shù)組 T[] ,不過(guò)非常麻煩的是 list.toArray(T[]) 中的 T[] 不知道如何得到,不知道如何弄到 T[] 的實(shí)例,new T[list.size()] 是沒(méi)辦法的。
第一個(gè)反應(yīng)是從 list 或是 List<T> 定義的 class 中得到成員的類(lèi)型,然后使用 Arrays.newInstance 來(lái)創(chuàng)建一個(gè),我花了好長(zhǎng)的時(shí)間都沒(méi)有能夠得到,后來(lái)和同事聊天時(shí),猜測(cè)是不是編譯完的 class 文件中根本就沒(méi)有類(lèi)型的信息,不過(guò)當(dāng)時(shí)沒(méi)能確定。
晚上接著猜數(shù)字的時(shí)候,舊事重提,google 了一下,看到了一個(gè)非常好的文章。
http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
將泛型說(shuō)明的非常清楚,其中一句是這樣的“Java 語(yǔ)言中的泛型基本上完全在編譯器中實(shí)現(xiàn),由編譯器執(zhí)行類(lèi)型檢查和類(lèi)型推斷,然后生成普通的非泛型的字節(jié)碼。這種實(shí)現(xiàn)技術(shù)稱(chēng)為擦除(erasure)(編譯器使用泛型類(lèi)型信息保證類(lèi)型安全,然后在生成字節(jié)碼之前將其清除)”。
驗(yàn)證了我的想法,在 class 文件中,根本就沒(méi)有泛型的信息。
實(shí)際上,聲明一個(gè)泛型數(shù)據(jù)的方法是
T[] array = (T[])new Object[length];
這樣,問(wèn)題解決,對(duì) Java 泛型的理解增加了一些。