第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/