• 第23条:请不要在新代码中使用原生态类型


    Java 1.5发行版本增加了泛型。在没有泛型之前,从集合中读取到的每一个对象都必须进行显式转换,一旦插入了类型错误的对象,在运行时出错才被发现。有了泛型之后,就可以告诉编译器每个集合中接受哪些对象类型,编译器会自动进行转换,并在编译时告知是否插入类型错误的对象。

    泛型指声明中具有一个或者多个类型参数的类或者接口。定义一组参数化的类型,构成格式为:类或者接口的名称,接着用尖括号<>把对应于泛型形式类型参数的实际类型参数列表括起来。例如List<String>,是一个参数化的类型,表示元素类型为String的列表,(String是与形式类型参数E相对应的实际类型参数)。

    每个泛型都定义一个原生态类型,即不带任何实际类型参数的泛型名称,如List<E>对应的原生态类型是List。

    在出现泛型之前,声明一个集合:

    //这个集合里面应该放stamp类的实例
    private final Collection stamps = ...;
    
    //如果把Coin类的实例放进去了,编译和运行照常进行
    stamps.add(new Coin());
    
    //直到从stamps集合中获取将coin取出来,却误以为它是stamp才会出错
    for(Iterator i = stamps.iterator(); i.hasNext(); ) {
        Stamp s = (Stamp) i.next();
    }

    出错应该越早发现越好,这样纠正的代价会越低。

    有了泛型之后:

    private final Collection<Stamp> s = ...;
    
    //编译的时候,这句代码就会出错
    s.add(new Coin());

    List和List<Object>的区别:前者逃避泛型检查,后者明确告诉编译器,它能持有任意类型的对象。虽然可以将List<String>传递给类型List的参数,但不能传递给类型List<Object>的参数。因为List<String>不是List<Object>的子类型。

    无限制通配类型Set<?>和Set的区别:如果不确定或者不关心实际的类型参数,就使用无限制通配类型,不能将任何元素(除null外)放到Set<?>中,如果尝试这样做,在编译时就会提示错误。

    必须使用原生态类型的例外:(源于泛型信息在运行时被擦除)

    1.类文字,如List.class,String[].class 是合法的,List<String>,List<?>.class 是不合法的。

    2.instanceof操作符

    if (o instanceof Set) {
        Set<?> m = Set<?> o;
        ...      
    }

    红色标记的部分不需要使用Set<?>,这样显得多余。但是,一旦确定o是Set,就将它转换为Set<?>。

  • 相关阅读:
    笔试的坑 onsubmit事件
    正则之
    笔试:找出一个字符串中字符出现最多的次数和该字符
    createDocumentFragment和insertAdjacentHTML
    css权威指南学习笔记--第七章
    使用gulp-minify-css的坑
    arguments[0]() 笔试题的坑
    快速搭建本地服务器
    voxel折腾指南
    力扣第72题 编辑距离
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5717827.html
Copyright © 2020-2023  润新知