您的位置:首页 > Web前端

Effective Java(列表优先于数组)

2017-09-25 15:32 211 查看

列表优先于数组

这条建议可引申出列表和数组的区别是什么,列表的内部实现。

  首先数组是协变的,这里的“变”指的是数据类型,对于以下代码确实合法的:

/**
*
* 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<?>


此条目几乎一直在说数组和泛型不能很好的配合使用,如果遇到泛型的情况,应该首先考虑列表。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java