《Effective Java》知识点(4)--泛型

26. 请不要使用原生态类型

      原生态类型是不带任何实际类型参数的泛型名称。原生态类型只是为了与引入泛型之前的遗留代码进行兼容和互用而提供的。

      如果使用原生态类型,就失掉了泛型在安全性和描述性方面的所有优势。使用原生态类型会在运行时导致异常,所以不要使用。如Set<Object>和Set<?>是安全的,而Set是不安全的。

      例外,一是必须在类文字(class literal)中使用原生态类型,如List.class;二是instanceof操作符需要使用原生态类型。

27. 消除非受检的警告

      警告类型:

a. 非受检转换(cast)警告

b. 非受检方法调用警告

c. 非受检参数化可变参数类型警告

d. 非受检转换(conversion)警告

      规则:

a. 要尽可能地消除每一个非受检警告

b. 如果无法消除警告,同时可以证明引起警告的代码是类型安全的,才可以用一个@SuppressWarnings("unchecked")注解来禁止这条警告。

c. 应该始终在尽可能小的范围内使用@SuppressWarnings,不要在整个类上使用。每当使用@SuppressWarnings都要添加一条注释,说明为什么这么做是安全的。

28. 列表优于数组

数组与泛型的不同:

a. 数组是协变的,如果Sub是Super的子类型,那么Sub[]就是Super[]的子类型;而泛型是可变的,List<Sub>不是List<Super>的子类型。

b. 数组是具体化的,在运行时知道它们的元素类型;而泛型在运行是擦除元素类型的。

因此数组提供了运行时的类型安全,但没有编译时的类型安全,而泛型则相反。

创建泛型数组是非法的。当数组与泛型混合使用遇到编译时错误或警告时,应该优先用泛型List。

29. 优先考虑泛型类

      使用泛型类比使用需要在客户端代码中进行转换的类型来得更加安全,也更容易。

30. 优先考虑泛型方法

       静态工具方法尤其适合泛型化。泛型方法和泛型类一样,使用起来比要求客户端转换输入参数并返回值的方法来得更加安全。

31. 利用有限制通配符来提升API的灵活性

     <? extends E>表示E的某个子类型 ,<? super E>表示E的某种超类。

     为了获得最大限度的灵活性,要在表示生产者(提供对象)或者消费者(接收对象)的输入参数上使用通配符类型。PECS表示producer-extends,consumer-super。所有的comparable和comparator都是消费者。

      不要用通配符类型作为返回类型。

      如果类型参数只在方法声明中出现一次,就可以用通配符取代它。

32. 谨慎混用泛型和可变参数

32.1 缺点

        当可变参数有泛型或参数化类型时,编译警告信息会产生混乱。

        当一个参数化类型的变量指向一个不是该类型的对象时,会产生堆污染。它导致自动生成转换失败,破坏了泛型系统的基本保证。

32.2 泛型可变参数方法在下列条件下是安全的:

        a. 它没有在可变参数数组中保存任何值。将值保存在泛型可变参数数组参数中是不安全的。

        b. 它没有对不被信任的代码开发该数组。允许另一个方法访问一个泛型可变参数数组是不安全的。

32.3 如果选择编写带有泛型或者参数化可变参数的方法,首先要确保该方法是类型安全的,然后用@SafeVarargs对它进行注解。

33. 优先考虑类型安全的异构容器

       所谓异构,就是所有键(key)都是不同类型的。将类型参数放在键上(即key参数化),而不是容器上,来获得可以保存不同类型对象的容器。一般用Class对象作为键, Class对象称作类型令牌。你也可以使用定制的键类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值