你的位置:首页 > Java教程

[Java教程]【Effective Java】8、优先考虑类型安全的异构容器


有的时候我们一个容器只有一个类型或几个类型并不能满足我们的要求,比如set中存放的元素类型都是同一种,map也就指定的两种

 

这里我们可以将键进行参数化,而不是将容器参数化,也就是我们可以给容器传一个键的类型,然后value用来放对应的实例,这样就可以存放多个不同的类型了

 

如:

package cn.xf.cp.ch02.item29;import java.util.HashMap;import java.util.Map;public class ManyTypeClass{  //一个存放数据的容器,由于键值类型是不确定的,那么值类型就只能是object类型  private Map<Class<?>, Object> data = new HashMap<Class<?>, Object>();    public <T> void putData(Class<T> type, T instance)  {    //吧数据放入进去    if(type != null)    {      //这里需要进行一下类型转换,通过Class的cast方法,因为泛型是基于擦除的,如果不进行验证的话,那么插入的数据到底是不是真的type类型就无法确定的了      data.put(type, type.cast(instance));    }  }    public <T> T getDate(Class<T> type)  {    //取出数据,由于数据存放进去是object类型的,那么取出来的时候就需要进行一次类型转换    return type.cast(data.get(type));  }    public static void main(String[] args)  {    ManyTypeClass mtc = new ManyTypeClass();    mtc.putData(String.class, "cutter_point");    mtc.putData(Integer.class, 0xcab145de);    mtc.putData(Class.class, ManyTypeClass.class);    mtc.putData(ManyTypeClass.class, mtc);        String dataString = mtc.getDate(String.class);    int dataInteger = mtc.getDate(Integer.class);    Class<?> dataClass = mtc.getDate(Class.class);    ManyTypeClass mtc1 = mtc.getDate(ManyTypeClass.class);        System.out.printf("%s %x %s %s%n", dataString,        dataInteger, dataClass.getName(), mtc1.getDate(String.class));  }}

 

运行显示结果:

 

 

异构成功,这个类可以存放各种不同的类型,但是注意不要放List<String>类型或List<Integer>类型,因为首先List<String>.class是不合法的,然后就算放个List进去,如果里面存放的不同的数据,key是List的,结果里面放的是List<Integer>类型,得到的结果并不能满意,也即是不能用在不可具体化的类型中。可以保存String或String[]但是如果是List<String>类型就无法编译了