Effective Java(列表优先于数组)
2017-09-25 15:32
246 查看
列表优先于数组
这条建议可引申出列表和数组的区别是什么,列表的内部实现。首先数组是协变的,这里的“变”指的是数据类型,对于以下代码确实合法的:
/** * * Created by zzy on 2017/8/17 */ public class Main { public static void main(String[] args) throws Exception{ Object[] objects = new Long[1];//Long objects[0] = "hello world";//字符串 System.out.println(objects[0]); } }
但合法仅存在于编译时期,在运行时会抛出以下错误:
泛型则是不可变的,这个不可变指的也是数据类型例如以下代码:
这段代码在编译期就会报错。综上,利用数组只有在运行时才会报错,利用列表在编译时就会报错,我们当然希望在错误能在编译时尽早发现。
大家可能都试图写过“泛型数组”:
List<String>[] lists = new ArrayList<String>[1];
但是却发现是错误的,编译时抛出Generic array creation错误,并且一时难以想象为什么不能创建泛型数组,书中举了以下例子来说明:
List<String>[] lists = new ArrayList<String>[1]; //先假设能创建泛型数组 List<Integer> intList = Arrays.asList(42); //Integer列表 Object[] objects = lists; //根据数组的“协变性”是合法的,例如上面提到的Object[] objects = new Long[1] objects[0] = intList; //List<String>和List<Integer>在运行时类型会被擦除为List String s = lists[0].get(0); //上一步操作过后,实际上取出的是一个initList,即取出是一个Integer,和String s类型不符
假设第一步不会报错,那么上面的例子在编译时就不会出错,但一到了运行时最后一句话就会抛出ClassCastException异常,也就是说与其在运行时出错,不如将它提前到编译时即不允许创建泛型数组。这就是为什么创建泛型数组是非法的原因:因为它不是类型安全的。要是它合法,编译器在其他正确的程序中发生的转换就会在运行时失败,并出现一个ClassCastExcetion异常。这就违背了泛型系统提供的基本保证。
不过有一个例外,以下的创建方式却是合法的:
List<?>[] lists = new ArrayList<?>[1];
泛型在运行时它的类型会被擦除,也就是说泛型是不可具体化的,它在运行时所包含的信息比它在编译时所包含的信息更少。唯一可具体化的参数化类型就是无限制的通配符类型,也就是上面提到的例子如
List<?>。
此条目几乎一直在说数组和泛型不能很好的配合使用,如果遇到泛型的情况,应该首先考虑列表。
相关文章推荐
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java(列表优先于数组)
- Effective Java 第三版——28. 列表优于数组
- Effective Java之列表由于数组(二十五)
- 第25条:列表优先于数组
- Effective Java之返回零长度的数组或者集合,而不是null(四十三)
- Effective Java(优先考虑类型安全的异构容器、用enum代替int常量)
- java 从零开始,学习笔记之基础入门<数组列表(ArrayList)>(九)
- Java数组与列表转换的java.lang.ClassCastException
- java 列表、集合与数组之间的转化
- 【Effective Java】8、优先考虑类型安全的异构容器