interface Staff { public int getSalary; } interface Passenger { public boolean isStanding; } class Me implements Staff, Passenger { @Override public boolean isStanding { return true; } @Override public int getSalary { return 2000; } }
public static <T> T toArray(List<T> list) { T t = (T[]) new Object[list.size()]; for (int i = 0, n = list.size; i < n; i++) { t[i] = list.get(i); } return t; }
public static void main(String[] args) { List<String> list = Arrays.asList("A","B"); for(String str :toArray(list)){ System.out.println(str); } }
编译没有任何问题,运行后出现如下异常:
1 2
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String; at com.study.advice100.Client100.main(Client100.java:16)
类型转换异常,也就是说不能把一个Object数组转换为String数组,这段异常包含了两个问题:
为什么Object数组不能向下转型为String数组:数组是一个容器,
只有确保容器内的所有元素类型与期望的类型有父子关系时才能转换,
Object数组只能保证数组内的元素时Object类型,却不能确保它们都是String的父类型或子类,
所以类型转换失败。
为什么是main方法抛出异常,而不是toArray方法:其实,是在toArray方法中进行的类型向下转换,
而不是main方法中。
那为什么异常会在main方法中抛出,应该在toArray方法的“ T t = (T[]) new Object[list.size()];”
这段代码才对呀?那是因为泛型是类型擦除的,toArray方法经过编译后与如下代码相同:
1 2 3 4
public static Object toArrayTwo(List list) { // 此处的强制类型转换没必要存在,只是为了与源代码对比 Object t = (Object[]) new Object[list.size()]; for (int i = 0, n = list.size; i < n; i++) { t[i] = list.get(i); } return t; } public static void main(String[] args) { List<String> list = Arrays.asList("A", "B"); for (String str : (String [])toArrayTwo(list)) { System.out.println(str); } }
public static <T> T toArray(List<T> list,Class<T> tClass) { //声明并初始化一个T类型的数组 T t = (T[])Array.newInstance(tClass, list.size); for (int i = 0, n = list.size; i < n; i++) { t[i] = list.get(i); } return t; }