优先考虑类型安全的异构容器

本文介绍了一种使用泛型的新方法,通过将Map的键参数化而非整体容器参数化,实现了在一个容器中插入和读取多种不同类型的元素,并保持类型安全。

      一般情况下,泛型最通常应用于集合,如set和Map,以及单元素的容器,如ThreadLocal等。在这些语法中一般情况下,这些容器都被充当被参数化了的容器,意味着每个容器只能有一个或者多个固定数目的类型参数。如一个Set只有一个类型参数,用于表示元素类型。一个Map有两个类型参数,表示它的键和值类型。(个人认为类型参数就是指定了类型的参数。这也是泛型的意义所在)

      但是有时候我们可能需要更多的灵活性,比如数据库行可以有任意多的列,每个列的类型可能不一样,如果能以类型安全的方式访问所有列就好了。目前,有一种方法可以实现,就是将键值(key)进行参数化而不是对整个容器进行参数化。然后将参数化的键值提交给容器,来插入或者获取值。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class Favorite {

	/**
	 * 注意这个地方Map的key进行了参数化,而非是Map本身
	 */
	private Map<Class<?>,Object>  map = new HashMap<Class<?>, Object>();
	private Map<List<?>,Object>  map2 = new HashMap<List<?>, Object>();
	
	
	
	public <E> void add(Class<E> type,E instance) {
		if(type!=null) {
			map.put(type, instance);
		}
	}
	
	public <E> void add(List<E> type,E instance) {
		if(type!=null) {
			map2.put(type, instance);
		}
	}
	 
	public <E> E get(Class<E> type) {
		Object object = map.get(type);
		return type.cast(object);
	}
	
	public  static void main(String[] args) {
		Favorite f = new Favorite();
		f.add(String.class, "string");//可以插入String类型
		f.add(Integer.class, Integer.valueOf(123));//可以插入int类型
		
		f.add(new ArrayList<String>(), "String");//可以插入String类型
		f.add(new ArrayList<Integer>(), 123);//可以插入int类型
		
		String s1 = f.get(String.class);
		Integer i = f.get(Integer.class);
		System.out.println(s1);
		System.out.println(i);
	}
	
}

  

上面的例子就是实现了一个可以指定多个类型的插入和读取,且是类型安全的。

这个例子需要注意的是

private Map<Class<?>,Object>  map = new HashMap<Class<?>, Object>();

每个Favorite实例都得到一个被称作map的私有
Map<Class<?>,Object> 
的支持。开始的时候,我们可能会将不能将任何东西放入到这个Map中去,因为其实无限制通配符,但是其实事实正好相反,我们可以删除任意类型的数据,原因是因为这个通配符是嵌套的,它不是属于通配符类型的Map的类型,而是他的key的类型。由此可见,每个键都可以有一个不同的参数化类型,本示例中Class<String> Class<Integer>。

 

 

转载于:https://www.cnblogs.com/chenfei0801/p/3665045.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值