列表优先于数组
不同点
- 数组和泛型的不同首先体现在数组是covariant的,所以如果Sub是Super的一个子类型,那么数组类型Sub[]也是数组类型Super[]的子类型。相反,泛型列表对此则有限制。这意味着:
1 | Object[] objectArray = new Long[1]; |
但如果使用列表:
1 | List<Object> ol = new ArrayList<Long>(); // Incompatible types |
- 数组是具化的,数组只有在运行时才能直到并检查元素类型,而泛型是通过擦除来实现的,这意味着泛型只在编译时进行类型约束的检查,而运行时是忽略元素类型的。因此无法混合使用数组和泛型,以下的操作都是不合法的:
1 | new List<E>[], new List<String>[], new E[] |
优先使用列表
当你强转成数组类型时,若得到一个泛型数组创建错误或者未检查强转警告,最好的解决办法是,总是优先采用集合类型List<E>,而不是数组类型E[]。
考虑这样一个类,构造器接受一个集合:
1 | public class Chooser { |
那么在使用时,我们每次都要在调用choose方法之后,将Object类型转换为需要的类型,有可能强转失败,如果我们使用泛型:
1 | public class Chooser<T> { |
这样会编译报错,除非我们强制换位Object数组:
1 | choiceArray = (T[]) choices.toArray(); |
这样只会产生一个警告,因为编译器无法保证运行时强转的安全性。当然,我们可以消除warning,但最佳的做法还是使用泛型列表:
1 | public class Chooser<T> { |