集合的强转出现的问题
看下面的代码:
private List<JobInfo> mJobList;
mJobList = Collections.synchronizedList(new ArrayList<JobInfo>());
这种写法是正确的,因为synchronizedList方法的返回值就是List集合的,但是看看下面这种写法
private ArrayList<JobInfo> mJobList;
mJobList = (ArrayList<JobInfo>)Collections.synchronizedList(new ArrayList<JobInfo>());
这种写法看起来时正确的,实际上会报异常“Caused by: java.lang.ClassCastException: java.util.Collections$SynchronizedRandomAccessList”
分析一下:
1. 函数的<T> List<T>是什么意思?
我知道的是返回一个List类型的集合,它里面存储的对象的类型是T,但是最前面的那个<T>又是什么意思呢?
在这个泛型方法中,类型参数是T,它位于函数的所有的修饰符之后,返回值之前,放在尖括号中,这个T是该函数的类型参数,而List<T>中的T是这个集合的类型参数
List<T>:参数化类型的返回值。
接下来让我们看看synchronizedList方法的源码:
public static <T> List<T> synchronizedList(List<T> list) {
if (list == null) {
throw new NullPointerException();
}
if (list instanceof RandomAccess) {
return new SynchronizedRandomAccessList<T>(list);
}
return new SynchronizedList<T>(list);
}
mJobList = (ArrayList<JobInfo>)Collections.synchronizedList(new ArrayList<JobInfo>());这行代码中,给synchronizedList方法传递了一个ArrayList类型的参数,ArrayList实现了RandomAccess接口,所以
会去执行return new SynchronizedRandomAccessList<T>(list);这行代码,这时我们来看看uml类图,其中SynchronizedRandomAccessList,SynchronizedList,SynchronizedCollection这三个类都是Collections工具类的static内部类
通过这个图我们可以看到,SynchronizedRandomAccessList是List的子类,他不是ArrayList类型的,因此上面代码的强转是不对的,此外我们还可以看出这是一个包装模式,关于包装模式以后再写。