8.5 泛型和数组

Java设计及的一个原则——如果一段代码在编译时没有提出“unchecked未经检查的转换”的警告,则程序在运行时不会引发ClassCastException异常。正是基于这个原因,所以数组元素的类型不能包含泛型变量、泛型形参,除非时无上限的类型通配符。但可以声明元素类型包含泛型变量或泛型形参的数组。也就是说List<String>[]数组,但不能创建ArrayList<String>[10]这样的数组。

假设Java支持创建ArrayList<String>[10]这样的数组对象,则有以下程序:

//下面代码实际上时不允许的
List<String>[] lsa=new ArrayList<String>[10];
//将lsa向上转型为Object[]类型的变量
Object[] oa=lsa;
List<Integer> li=new ArrayList<>();
li.add(3);
//将List<Integer>对象作为oa的第二个元素
//下面代码没有任何警告
oa[1]=li;
//下面代码也不会出现任何警告,但会引发ClassCastException异常
String s=lsa[1].get(0);

上面代码违背了Java泛型设计的原则。上述过程,图示为:

 将程序改成下面形式:

 1 import java.util.*;
 2 public class GenericAndArray1
 3 {
 4     public static void main(String[] args)
 5     {
 6         // 下面代码编译时有“[unchecked] 未经检查的转换”警告
 7         List<String>[] lsa = new ArrayList[10];
 8         // 将lsa向上转型为Object[]类型的变量
 9         Object[] oa = lsa;
10         List<Integer> li = new ArrayList<>();
11         li.add(3);
12         oa[1] = li;
13         // 下面代码引起ClassCastException异常
14         String s = lsa[1].get(0);              //
15     }
16 }
17 ---------- 编译Java ----------
18 注: GenericAndArray1.java使用了未经检查或不安全的操作。
19 注: 有关详细信息, 请使用 -Xlint:unchecked 重新编译。
20 
21 输出完成 (耗时 1 秒) - 正常终止

 上面代码List<String>[]类型的数组变量是可以的,但是不允许创建new List<String>[]类型的对象,所以创建一个类型为ArrayList[10]的数组对象,这也是允许的。只是把一个ArrayList[10]对象赋给List<String>[]变量时,将会有编译警告:“[unchecked] 未经检查的转换”,即编译器不保证上面这段代码是类型安全的。因此当程序运行到String s = lsa[1].get(0); 将出现运行错误。

Java允许创建无上限的通配符泛型数组,例如new ArrayList<?>[10],因此可以将第一段代码改为使用无上限的通配符泛型数组,在这种情况下,程序不得不进行强制类型转换。下面代码正确:

 1 import java.util.*;
 2 public class GenericAndArray2
 3 {
 4     public static void main(String[] args)
 5     {
 6 
 7         List<?>[] lsa = new ArrayList<?>[10];
 8         Object[] oa = lsa;
 9         List<Integer> li = new ArrayList<>();
10         li.add(3);
11         oa[1] = li;
12         Object target = lsa[1].get(0);
13         //程序在进行强制类型转换时,需要通过instanceOf运算符判断它的数据类型
14         if (target instanceof String)
15         {
16             // 下面代码安全了
17             var s = (String) target;
18         }
19     }
20 }
原文地址:https://www.cnblogs.com/weststar/p/12614253.html