泛型

23,请不要在新代码中使用原生态类型 声明中具有一个或多个类型参数的类或接口,就是泛型类或者接口。泛型类和接口统称为泛型。List
每个泛型都定义了一个原生态类型,即不带任何实际参数的泛型名称。例如List相对应的原生态类型是List。
如果使用原生类型,就失掉了泛型在安全性和表述性方面的所有优势。
24,消除非受检警告 【泛型】要尽可能地消除每一个非受检警告。如果无法消除警告,同时可以证明引起警告的代码时类型安全的,(只有在这种情况下才)可以用一个@SuppressWarings("unchecked")注解来禁止这条警告。
每当使用@SuppressWarings("unchecked")注解时,都要添加一句注解,说明为什么这么做是安全的。
25,列表优先于数组

  • 首先,数组是协变得。
简单来说,如果Sub为Super的子类型,那么数组Sub[]就是Super[]的子类型。但泛型是不可变的:对于任意两个不同类型的泛型Type1和Type2,List不是List的子类型。
//将String放入Long容器中是错误的! Object[] objectArray = new Long[]; objectArray[0] = "I don't fit";

  • 数组是具体化的。因此数组会在运行时才知道并检查他们的元素类型约束,如果企图将String保存到Long数组中,就会得到一个ArrayStoreException异常。而泛型是通过擦除来实现的,使泛型可以与没有使用泛型的代码随意进行互用。
26.优先考虑泛型 使用泛型比使用需要在客户端代码中进行转换的类型来得安全,也更加容易。在设计新类型时,要确保它们不需要使用这种转换就可以使用。这意味着要把类做成泛型。只要时间允许,就把现有的类型都泛型化。这对于这些类型的新用户来说会变得更加轻松,又不会破坏现有的客户端。
27,优先考虑泛型方法 就如同类可以从泛型中受益一般,方法也一样。静态工具方法尤其适合于泛型化。
泛型方法的一个显著特点是,无需明确指定类型参数的值,不像调用泛型构造器的时候是必须指定的(和方法声明泛型相同E)。
28,利用有限制通配符来提升API的灵活性 为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符类型。如果某个输入参数既是生产者,优势消费者,那么通配符类型对你就没有什么好处了:因为你需要严格的类型匹配,这是不用任何通配符而得到。
PECS表示producer-extends,consumer-super。
换句话说,如果参数化类型表示一个T生产者,就使用;如果它表示一个T消费者,就使用
一般来说,如果类型参数只在方法声明中出现一次,就可以用通配符取代它;如果是有限制的类型参数,就用有限制的通配符取代它。
29,优先考虑类型安全的异构容器 泛型最常用于集合,如Set和Map,以及单元素的容器,如ThreadLocal。在这些用法中。它都被充当被参数化了的容器。这样就限制你每个容器只能有固定数目的类型参数。
异构:不像普通的map,它的所有键都是不同类型。
总而言之,集合API说明了泛型的一般用法,限制你每个容器只能有固定数目的类型参数。你可以通过将参数类型放在键上而不是容器上来避免这一限制。对于这种类型安全的异构容器,可以用Class对象作为键。以这种方式使用的Class对象称作类型令牌。你也可以使用定制的键类型。例如:用一个DataBaseRow类型表示一个数据库行(容器),用泛型Column作为它的键。

    推荐阅读