欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《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