23.请不要在新代码中使用原生态类型24.消除非受检警告25. 列表优于数组26.优先考虑泛型27.优先考虑泛型方法28.利用有限制通配符来提升API的灵活性29.优先考虑类型安全的异构容器 23.请不要在新代码中使用原生态类型声明中具有一个或者多个类型参数的类或者接口就是泛型, 泛型类和接口统称为泛型.Set是个参数化类型, 表示可以包含任何对象类型的一个集合; Set<?>则是一个通配符类型, 表示只能包含某种未知对象类型的一个集合; Set则是一个原生态类型, 它脱离了泛型系统, 前两种是安全的, 最后一种不安全 参数化的类型 List实际类型参数 String泛型 List形式类型参数 E无限制通配符类型 List<?>原生态类型 List有限制类型参数 递归类型限制 >有限制通配符类型 List<? extends Number>泛型方法 static List asList(E[] a)类型令牌 String.class 24.消除非受检警告编译器警告: 非受检强制转化警告, 非受检方法调用警告, 非受检普通数组创建警告, 以及非受检转换警告等. 尽可能消除每一个非受检警告如果无法消除警告, 同时可以证明引起警告的代码是类型安全的, 只有在这种情况下, 才可以用一个@SuppressWarning(“unchecked”)注解来禁止这条警告.应该始终在尽可能小的范围中使用注解.每当使用注解时, 都要添加一条注释, 说明为什么这么做是安全的. 25. 列表优于数组数组与泛型相比, 有两个重要的不同点: 数组是斜边的, 泛型是不可变的数组是具体话的, 因此数组会在运行时才知道并检查他们的元素类型约束; 相比之下, 泛型则是通过擦除来实现的, 因此泛型只在编译时强化他们的类型信息, 并在运行时丢弃他们的元素类型信息 一般来说, 数组和泛型不能很好的混用, 如果你发现自己将他们混合起来使用, 并且得到了编译时错误或者警告, 你的第一反应就应该是用列表代替数组. 26.优先考虑泛型将类泛型化的第一个步骤是给它的声明添加一个或者多个类型参数, 然后用相应的类型替换所有的Object类型 27.优先考虑泛型方法 28.利用有限制通配符来提升API的灵活性参数化类型是不可变的. 换句话说, 对于任何两个截然不同的类型Type1和Type2而言, List既不是List的子类型, 也不是它的超类型. 例如List不是List的子类型. Java提供了一种特殊化的参数化类型, 称作又限制的通配符类型, 来处理类似的情况. PECS, producer-extends consumer-super如果参数化类型表示一个T生产者, 就使用<? extends T>; 如果它表示一个T消费者, 就是用<? super T>, 且所有的comparable和conparator都是消费者 一般来说, 如果参数类型只在方法声明中出现一次, 就可以用通配符取代它, 如果是无限制的类型参数, 就用无限制的通配符取代它, 如果是有限制的类型参数, 就用有限制的通配符取代它. 29.优先考虑类型安全的异构容器Class在jdk1.5版本中被泛型化了, 类的类型从字面上来看不再只是简单的Class, 而是Class, 例如String.class属于Class类型. 当一个类的字面文字被用在方法中, 来表达编译时和运行时的类型信息时, 就被称作type token. 示例代码: 构建一个Favorites类, 允许其客户端从任意数量的其他类中, 保存并获取一个”最喜爱”的实例. /** * Favorites * * @author gavin * @version 2020/7/18 */public class Favorites { private Map<Class<?>, Object> favorites = new HashMap<>(); public <T> void putFavorites(Class<T> type, T instance) { if (type == null) { throw new NullPointerException("type is null!"); } favorites.put(type, instance); } public <T> T getFavorites(Class<T> type) { return type.cast(favorites.get(type)); }} Favorites类是类型安全的, 也是异构的: 不像普通的map, 它的所有键都是不同类型的.Favorites类有两种局限性值得注意, 首先, 以它的原生态形式使用Class对象, 会造成编译时未受检警告优化如下: // 如果放入的实例不是type类型的, 会报ClassCastException favorites.put(type, type.cast(instance)); 第二种局限性在于它不能用在不可具体化的类型中.换句话说, 可以保存String或String[], 但不能保存List, 因为无法为List获得一个Class对象, List和List共用一个List.class对象.对于第二种局限性, 还没有完全令人满意的解决办法, 有一种方法称作super type token, 在解决这一局限性方面做了很多努力, 但仍有它自身的局限性.