第25条:列表优先于数组
数组与泛型相比,有两个重要的不同点。数组是协变的(如果Sub是Super的子类型,那么数组类型Sub[]是Super[]的子类型),相反,泛型是不可变得,对于任意两个不同的类型T1和T2,List<T1>和List<T2>没有子类型或超类型的关系。
//这段代码在运行时出错 Object[] o = new Long[1]; o[0] = "I don't fit it"; //这段代码在编译时出错 List<Object> o = new ArrayList<Long>(); o.add("I don't fit it";
一段代码:
static <E> E reduce(List<E> list, Function<E> f, E initVal) { E[] snapshot = (E()) list.toArray(); E result = initVal; for(E e : snapshot) result = f.apply(result, e);
return result; }
会有一条警告,编译器无法再编译时知道E是什么,所以是一个非受检的警告。
修改成列表代替数组:
static <E> E reduce(List<E> list, Function<E> f, E initVal) { List<E> snapshot; synchronized(list) { snapshot = new ArrayList<E>(list); } E result = initVal; for(E e : snapshot) result = f.apply(result, e); return result; }
这样不会再收到警告,因为编译器可以保证类型转换自动进行,不会出错。