java数组子类型_[改善Java代码]数组的真实类型必须是泛型类型的子类型
List接口的toArray方法可以把一個(gè)結(jié)合轉(zhuǎn)化為數(shù)組,但是使用不方便,toArray()方法返回的是一個(gè)Object數(shù)組,所以需要自行轉(zhuǎn)變.
toArray(T[] a)雖然返回的是T類型的數(shù)組,但是還是需要傳入一個(gè)T類型的數(shù)組,這也挺麻煩的.我們期望輸入的是一個(gè)泛型化的list,這樣就能轉(zhuǎn)化為泛型數(shù)組了.
看代碼:
1 importjava.util.Arrays;2 importjava.util.List;3
4 public class Client{5 public static T[] toArray(Listlist){6 T[] t = (T[])newObject[list.size()];7 for(int i=0,n=list.size();i
13 public static voidmain(String[] args) {14 List list = Arrays.asList("A","B");15 for(String str:toArray(list)){//這一句報(bào)錯(cuò)16 System.out.println(str);17 }18 }19 }
編譯沒有任何問題,運(yùn)行后出現(xiàn)如下異常;
Exception in thread "main"java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at cn.summerchill.test.Client.main(Client.java:17)
類型轉(zhuǎn)換異常,也就是說,不能把一個(gè)Object數(shù)組轉(zhuǎn)換為String數(shù)組,這段異常包含了兩個(gè)問題:
1.為什么Object數(shù)組不能向下轉(zhuǎn)型為String數(shù)組?
數(shù)組是一個(gè)容器,只有確保容器內(nèi)的所有元素類型與期望的類型有父子關(guān)系時(shí)才能轉(zhuǎn)換,Object數(shù)組只能保證數(shù)組內(nèi)的元素是Object類型.卻不能確保它們都是String的父類型或子類,所以轉(zhuǎn)換失敗.
2.為什么是main方法拋出異常,而不是toArray方法?
其實(shí),是在toArray方法中進(jìn)行的類型向下轉(zhuǎn)換,而不是main方法中,那為什么異常會(huì)在main方法中拋出,應(yīng)該在toArrya方法的 ??T[] t = (T[])new Object[list.size()] 這段才對啊....
那是因?yàn)榉盒褪穷愋筒脸?toArray方法經(jīng)過編譯后與如下代碼相同:
1 importjava.util.Arrays;2 importjava.util.List;3
4 public class Client{5 public staticObject[] toArray(List list){6 //此處的強(qiáng)制類型沒必要存在,只是為了保持與源代碼對比
7 Object[] t = (Object[])newObject[list.size()];8 for(int i=0,n=list.size();i
14 public static voidmain(String[] args) {15 List list = Arrays.asList("A","B");16 for(String str:(String[])toArray(list)){17 System.out.println(str);18 }19 }20 }
閱讀完此段代碼就很清楚了,toArray方法返回后會(huì)進(jìn)行一次類型轉(zhuǎn)換,Object數(shù)組轉(zhuǎn)換成了String數(shù)組,于是就報(bào)了ClassCastException異常了.
Object數(shù)組不能轉(zhuǎn)換成String數(shù)組,T類型又無法在運(yùn)行期獲得,那該如何解決這個(gè)問題呢?
其實(shí)要想把一個(gè)Object數(shù)組轉(zhuǎn)換成為String數(shù)組,只要Object數(shù)組的實(shí)際類型也是String就可以了.
1 public class Client{2 public static voidmain(String[] args) {3 //objArray的實(shí)際類型和表面類型都是String數(shù)組
4 Object[] objArray = {"A","B"};5 //拋出ClassCastException
6 String[] strArray =(String[])objArray;7
8 String[] ss = {"A","B"};9 //objs的真實(shí)類型是String數(shù)組,顯示類型為Object數(shù)組
10 Object[] objs =ss;11 //順利轉(zhuǎn)換為String數(shù)組
12 String[] strs =(String[])objs;13 }14 }
知道了上面,把泛型數(shù)組聲明為泛型類的子類型
1 importjava.lang.reflect.Array;2 importjava.util.Arrays;3 importjava.util.List;4
5 public class Client{6
7 public static T[] toArray(List list, ClasstClass) {8 //聲明并初始化一個(gè)T類型的數(shù)組
9 T[] t =(T[]) Array.newInstance(tClass, list.size());10 for(int i=0,n=list.size();i list = Arrays.asList("A", "B");17 for (String str : toArray(list,String.class)) {18 System.out.println(str);19 }20 }21 }
通過反射類Array聲明了一個(gè)T類型的數(shù)組,由于我們無法在運(yùn)行期獲得泛型類型的參數(shù),因此就需要調(diào)用者主動(dòng)傳入T參數(shù)類型.此時(shí),客戶端再調(diào)用就不會(huì)出現(xiàn)任何異常了.
在這里我們看到,一個(gè)泛型類(特別是泛型集合)轉(zhuǎn)變?yōu)榉盒蛿?shù)組時(shí),泛型數(shù)組的真實(shí)類型不能是泛型類型的父類型(比如頂層類Object),只能是泛型類型的子類型(當(dāng)然包含自身類型),否則就會(huì)出現(xiàn)類型轉(zhuǎn)換異常.
總結(jié)
以上是生活随笔為你收集整理的java数组子类型_[改善Java代码]数组的真实类型必须是泛型类型的子类型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java多线程对数组求和_java 多线
- 下一篇: java连接stk外部接口_SLWSTK