泛型

1、泛型单例工厂——示例

interface UnaryFunction<T>{
	T apply(T arg);
}

public class SingletonFactory {
	//Genric singleton factory pattern
	private static UnaryFunction<Object> IDENTITY_FUNCTION=
		new UnaryFunction<Object>(){
			@Override
			public Object apply(Object arg) {
				return arg;
			}
		};
	
	//IDENTITY_FUNCTION is stateless and its type parameter is
	//unbounded so it's safe to share one instance across all types.
	@SuppressWarnings("unchecked")
	public static <T> UnaryFunction<T> identityFunction(){
		return (UnaryFunction<T>)IDENTITY_FUNCTION;
	}
	
	public static void main(String[] args) {
		String[] strings = {"jute", "hemp", "nylon"};
		UnaryFunction<String> sameString = identityFunction();
		for( String s : strings ){
			System.out.println( sameString.apply(s) );
		}
		
		Number[] numbers = {1, 2.0, 3l};
		UnaryFunction<Number> sameNumber = identityFunction();
		for( Number n : numbers ){
			System.out.println( sameNumber.apply(n) );
		}
	}
}

要点:

a、底层实例 IDENTITY_FUNCTION 的“实际类型参数”用Object,这样可以保存所有对象的应用。

b、泛型方法中强制转换。因为泛型的擦除,这里仅仅只有个警告。

而如下的用法是错误的(无法通过编译):

List<String> listString = (List<String>) new ArrayList<Object>();

因为List<String> 与 ArrayList<Object>是没有任何关系的!

而一旦放在泛型方法中就仅仅是个警告,这就是奇妙之处!

public class TypeParamaterObject {
	private static List<Object> IDENTITY= new ArrayList<Object>();
	
	@SuppressWarnings("unchecked")
	public static <T> List<T> identityFunction(){
		return (List<T>)IDENTITY;
	}
	
	public static void main(String[] args) {
		List<String> listString = identityFunction();
		listString.add("aaaa");
		listString.add("bbbb");
		listString.add("ccc");
		
		//Cast right
		String s = listString.get(0);
		CollectionPrintHelper.printCollection( listString );
	}
}
实际应用:Collections.reverseOrder( )
    public static <T> Comparator<T> reverseOrder() {
        return (Comparator<T>) REVERSE_ORDER;
    }

    private static final Comparator REVERSE_ORDER = new ReverseComparator();

    /**
     * @serial include
     */
    private static class ReverseComparator<T>
	implements Comparator<Comparable<Object>>, Serializable {

	// use serialVersionUID from JDK 1.2.2 for interoperability
	private static final long serialVersionUID = 7207038068494060240L;

        public int compare(Comparable<Object> c1, Comparable<Object> c2) {
            return c2.compareTo(c1);
        }

        private Object readResolve() { return reverseOrder(); }
    }

2、类型安全的异构容器——示例

public class Favorites {
	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) );
	}
	
	public static void main(String[] args) {
		Favorites f = new Favorites();
		f.putFavorite(String.class, "Java");
		f.putFavorite(Integer.class, 500);
		f.putFavorite(Class.class, Favorites.class);
		
		String fString = f.getFavorite(String.class);
		int fInt = f.getFavorite(Integer.class);
		Class<?> fClass = f.getFavorite(Class.class);
		
		System.out.printf("%s %d %s%n", fString, fInt, fClass);
	}
}

缺陷:客户端使用原生态Class对象,可以轻松破坏Favorites 类型安全。

Favorites f = new Favorites();
Class sClass = String.class;
f.putFavorite(sClass, 200);

这样的错误要等到执行:String fString  =  f.getFavorite(String.class); 才会暴露!

修复:

	public <T> void putFavorite( Class<T> type, T instance ){
		if( type == null ){
			throw new NullPointerException("type is null");
		}
		favorites.put(type, type.cast(instance));
	}
插入时就报错!































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值