《effective java》之四:泛型 博客分类: Java effective
程序员文章站
2024-02-15 08:55:28
...
第23条:请不要在新代码中使用原生态类型:
Set<Object>是个参数化类型,表示可以包含任何对象的一个集合;Set<?>则是一个通配符类型,表示只能包含某种未知对象类型的一个集合,既不能从里面拿到一个元素去赋值,也不能增加一个元素,可以删除。
第24条:消除泛型的非受检警告 unchecked warning:
如果无法消除警告,同时可以证明引起警告的代码是类型安全的,才可以用@SuppressWarning("unchecked")注解来消除这条警告。同时用注释把禁止该警告的原因记录下来。
第25条:列表优于数组:
数组是协变的covariant,其实就是表示如果Sub为Super的子类型,则Sub[]就是Super[]的子类型,而泛型不同。所以创建泛型数组或者参数化数组都是不合法的,编译不通过。
为了说明为什么不可行,一个经典例子:
List<String>[] stringLists = new List<String>[1]; List<Integer> intList = Arrays.asList(42); Object[] objects = stringLists; object[0] = intList; String s = stringLists[0].get(0);
假设第一行是合法的,那么运行时会抛出ClassCastException。
第26条:优先考虑泛型:
第27条:优先考虑泛型方法:
public class RecursiveTypeBound { // Returns the maximum value in a list - uses recursive type bound public static <T extends Comparable<T>> T max(List<T> list) { Iterator<T> i = list.iterator(); T result = i.next(); while (i.hasNext()) { T t = i.next(); if (t.compareTo(result) > 0) result = t; } return result; } public static void main(String[] args) { List<String> argList = Arrays.asList(args); System.out.println(max(argList)); } }
第28条:利用有限制通配符提升API的灵活性:
extends和super通配符使用规则:
在表示生产者的输入参数上使用extends。
而消费者输入参数上使用super
producer-extends,consumer-super
不要用通配符作为返回类型。
public class Union { public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2) { Set<E> result = new HashSet<E>(s1); result.addAll(s2); return result; } // Simple program to exercise flexible generic method public static void main(String[] args) { Set<Integer> integers = new HashSet<Integer>(); integers.add(1); integers.add(3); integers.add(5); Set<Double> doubles = new HashSet<Double>(); doubles.add(2.0); doubles.add(4.0); doubles.add(6.0); // Won't compile; see page 137 // Set<Number> numbers = union(integers, doubles); // Explicit type parameter is necessary here Set<Number> numbers = Union.<Number> union(integers, doubles); System.out.println(numbers); } }
public class Swap { public static void swap(List<?> list, int i, int j) { swapHelper(list, i, j); } // Private helper method for wildcard capture private static <E> void swapHelper(List<E> list, int i, int j) { list.set(i, list.set(j, list.get(i))); } public static void main(String[] args) { // Swap the first and last argument and print the resulting list List<String> argList = Arrays.asList(args); swap(argList, 0, argList.size() - 1); System.out.println(argList); } }
第29条:优先考虑类型安全的异构容器:
public class Favorites { // Typesafe heterogeneous container pattern - implementation private Map<Class<?>, Object> favorites = new HashMap<Class<?>, Object>(); public <T> void putFavorite(Class<T> type, T instance) { if (type == null) throw new NullPointerException("Type is null"); favorites.put(type, instance); } public <T> T getFavorite(Class<T> type) { return type.cast(favorites.get(type)); } // Typesafe heterogeneous container pattern - client public static void main(String[] args) { Favorites f = new Favorites(); f.putFavorite(String.class, "Java"); f.putFavorite(Integer.class, 0xcafebabe); f.putFavorite(Class.class, Favorites.class); String favoriteString = f.getFavorite(String.class); int favoriteInteger = f.getFavorite(Integer.class); Class<?> favoriteClass = f.getFavorite(Class.class); System.out.printf("%s %x %s%n", favoriteString, favoriteInteger, favoriteClass.getName()); } }
本人博客已搬家,新地址为:http://yidao620c.github.io/
推荐阅读
-
《effective java》之八:异常 博客分类: Java effective
-
Effective Java读书笔记、感悟——2.1对所有对象都通用的方法之equals 博客分类: Java_SE effectivejava对象通用方法equals
-
《effective java》之四:泛型 博客分类: Java effective
-
《effective java》之一:创建和销毁对象 博客分类: Java effectivejava
-
《effective java》之十:序列化 博客分类: Java effective
-
Effective Java读书笔记、感悟——1.创建和销毁对象 博客分类: Java_SE effectivejava对象创建对象销毁
-
《effective java》之五:枚举和注解 博客分类: Java effective
-
《effective java》之七:方法 博客分类: Java effective
-
《effective java》之三:类和接口 博客分类: Java effectivejava
-
《effective java》之二:对于所有对象都通用的方法 博客分类: Java effectivejava