Java:使用泛型的类包装器

时间:2014-01-27 22:51:13

标签: java generics typechecking

我会以某种方式在HashMap中存储许多不同的类型,但是当我提取它们时,它们将被很好地键入(而不是对象)。

所以我想一下使用泛型的包装器

 public class Value <T>
 {
     private T innerValue ;

     public Value ( T _value )
     {
         innerValue = _value ;
     }

     public T read ()
     {
         return innerValue ;
     }
 }

但是对于我做的测试它不起作用:

 Value <Integer> va = new Value <Integer> ( 1 ) ;
 Value vc = va ;
 int restA = vc.read();

但我得到一个设计时错误,因为vc.read()将返回一个Object()而不是一个Integer。 那么我该怎么做才能避免这种行为呢? (如果可能的话,我会采用一种解决方案来阻止'va'丢失关于T的信息而不是其他解决方法)

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您已将va投放到原始Valuevc。当您使用类的原始形式时,T泛型类型参数将替换为Object。因此,您无法将Object分配给int

如果您只是致电va.read(),那么它会返回Integer,在int分配后,restA将被取消装箱。

答案 1 :(得分:1)

  

我会以某种方式在HashMap中存储许多不同的类型,但在一个   当我提取它们时,它们将被很好地打字(而不是一个   对象)。

简短的回答是:这是不可能的。并且类型擦除不是原因:在编译时获取此信息根本没有意义。假设Java编译器具有某种机制来跟踪填充到HashMap中的对象类型。然后它也必须应对这样的事情:

HashMap<Integer, Value<?>> myMap = new HashMap<Integer, Value<?>>;
if (Math.random() > 0.5) {
    myMap.put(0, new Value<String>("hello world"));
} else {
    myMap.put(0, new Value<MacaroniExtruder>(new MacaroniExtruder()));
}
[whatDoYouWantToWriteHere?] value = myMap.get(0);

你想要的可能更像“类型联盟”。不幸的是,它既不存在于Java中,也不存在于Scala中(我们拥有case-classes,几乎同样适用于它)。所以你所能做的就是:

A)使用多态,定义一个合适的接口,使具体的实现变得完全不相关,并使用该接口作为哈希Map的第二个参数(首选)。

B)使用instanceof和long if-else开关(丑陋)

相关问题