泛型(Generic)

泛型的作用:告诉编译器每个集合中可接受哪些对象类型,编译器自动地为你的插入进行转化,并在编译时告知是否插入错误的对象。这样使程序既更加安全也更加清楚。

第二十三条、请不要在新代码中使用原生态类型

  1. 声明中具有一个或者多个类型参数的类或者接口,就是泛型类或者接口.

    例:List接口只有单个类型参数E,表示列表的元素类型。List<E>
    每种泛型定义一组参数化的类型,构成的格式为:先是类或者接口名,接着用尖括号<>把对应于泛型形式类型参数的实际类型参数列表括起来。如:List<String>

  2. 每个泛型都定义一个原生态类型(raw type),即不带任何实际类型参数的泛型名称。如:与List对应的原生类型是List。但如果使用原生态类型,就失掉了泛型在安全性和表述性方面的所有优势。

  3. 安全的替代方法:无限制的通配符类型(unbounded wildcard type):

    如果使用泛型,但不确定或者不关心实际的类型参数,就可以使用一个问号代替。
    那么,Set

第二十四条、消除非受检警告

  1. 泛型编程时会遇到许多编译器的警告:非受检强制转化警告(unchecked cast warning)、非受检方法调用警告、非受检普通数组创建警告、以及非受检转换警告(unchecked conversion warnings)。有些警告可以根据编译器来消除,但是有些警告难以消除,同时可以证明引起警告的代码是类型安全的,可以用一个@SuppressWarnings("unchecked")来禁止这条警告。

  2. @SuppressWarnings("unchecked")可以在任何粒度的级别中,应该始终在尽可能小的范围内使用SuppressWarnings注解。它通常是个变量声明,或是非常简单的方法或者构造器。


第二十五条、列表优先于数组

  1. 数组与泛型相比的不同点:

    • 数组是协变的(covariant),即如果Sub为Super的子类型,即Sub[]为Super[]的子类型。而泛型是不可变的。这么看来,数组是有缺陷的。

              //编译时是合法的
              Object[] objectArray = new Long[1];
              objectArray[0] = "I don't fit in";
              //Won't Compile
              List<Object> ol = new ArrayList<Long>();
              ol.add("I don't fit in");  
    • 数组是具体化的(reified),因此数组会在运行时才知道检查它们的元素类型约束;相比之下,泛型则是通过擦除(erasure)来实现的,因此泛型只在编译时强化它们的类型信息,并在运行时丢弃它们的元素信息。
    • 由于上面的两个区别,数组和泛型不能很好地混合使用。
  2. 从技术的角度说:像EList<E>List<String>这样的类型应称作不可具体化的类型(直观上说是指其运行时表示法包含的信息比它编译时表示包含法的信息更少的类型。)唯一可具体化的参数化类型是无限制的通配符类型,如List<?>和Map<?,?>虽然不常用,但创建无限制通配符类型的数组是合法的。

  3. 总结:数组和泛型有着非常不同的类型规则。数组是协变且可以具体化。泛型是不可变的且可以被擦除,一般数组和泛型不能很好地混合使用,如果编译错误得到警告,第一反应时用列表代替数组。


第二十六条、优先考虑泛型


第二十七条、优先考虑泛型方法


第二十八条、利用有限制通配符来提升API的灵活性

  1. Java提供了一种特殊的参数化类型,称作有限制的通配符类型:

    <? extends E >E的某个子类型,确定了子类型之后,每个类型都是自己的子类型。
    <? super E> E的某个超类,每个类型都是自己的超类。

  2. 为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符类型,如果某个输入参数既是生产者又是消费者,那么通配符类型就没有用了,因为你需要的是严格的类型匹配。

  3. 助记符:PECS: producer-extends,consumer-super

    如果参数化类型表示一个T生产者,就使用<? extends T>,如果表示一个T消费者,则使用<?super T>,所有的comparable和comparator都是消费者。

  4. 不要用通配符类型作为返回类型! 通配符类型对于类的用户来说应是无形的。


第二十九条、优先考虑类型安全的异构容器

  1. 泛型最常用于集合(Set或者Map)以及单元素的容器。在这些用法中,它都充当被参数化了的容器。这样就限制了每个容器只能有固定数目的类型参数,一个Set只有一个类型参数,表示它的元素类型,一个Map有两个类型参数,表示它的键和值得类型。

  2. 可以通过将类型参数放在键上而不是容器上来避开这种限制,对于这种类型安全的异构容器,可以用Class对象作为键。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值