带有各种泛型类对象的java.util.Map

时间:2014-08-31 17:58:29

标签: java generics hashmap

我喜欢拥有一个java.util.Map,它包含不同的泛型类对象。在我的案例中,处理程序如下:

public interface Handler<s>{
 public void encode (S data, OutputStream out);
 public S decode (InputStream in, long length);
}

我有实现类,例如:

public class SpecializedHandler implements Handler<FirstSpecialItem>{
 public void encode (SpecialItem data, OutputStream out){
  // do something
 }
 public SpecialItem decode(InputStream in, long length){
  // do something
 }
}

和另一个实现Handler的类。

对于FirstSpecialItem和SecondSpecialItem存在父类 AbstractSpecialItem

因为我在使用编码和解码时遇到了很多问题,所以我最终得到了以下映射,它可以使用解码和编码,如下所示:

Map<Long, Handler<? super AbstractSpecialItem>> handlers;
// I can use it as follows
AbstractSpecialItem item = new FirstSpecializedItem();

handlers.get(1L).encode(item,System.out);   
AbstractSpecialItem returnVal = handlers.get(1L).decode(System.in, 100L);

但是,我无法通过添加不同的Handler实现来创建地图,例如:

SpecializedHandler a = new SpecializedHandler();
SpecializedSecondHandler b = new SpecializedSecondHandler();
Map<Long, Handler<? super AbstractSpecialItem>> handlers = new HashMap<Long,Handler<? super AbstractSpecialItem>>();
handlers.put(0L, a); // does not work
handlers.put(1L, b); // does not work 

Eclipse总是说这些值不适用于Map。 我认为这种行为是有效的,并试图更好地理解泛型和PECS原则(浏览网页和一些书籍)。但我仍然没有得到它,找出解决方案。我有Handler类及其特殊泛型类型,并能够使用方法(编码,解码)以及创建处理程序Map。

2 个答案:

答案 0 :(得分:0)

如果您使用Map<Long, Handler<? extends AbstractSpecialItem>>而不是Map<Long, Handler<? super AbstractSpecialItem>>,它应该有效。请注意扩展而非超级,为了更详细的解释,我建议您查看此问题的答案: java generics super vs. extends

这是一个有效的例子:

import java.io.*;
import java.util.*;

public class Test {
  public abstract class A<T extends Closeable> { }
  public class B<T extends Closeable> extends A<T> { }
  public class C<T extends Closeable> extends A<T> { }

  public Map<String, A<? extends Closeable>> map = new HashMap<>();
  // instance initializer
  {
    map.put("1", new B<InputStream>());
    map.put("2", new C<Reader>());
  }
}

答案 1 :(得分:0)

在您的情况下,您应该使用

Map<Long, Handler<? extends AbstractSpecialItem>> handlers = new HashMap<Long, Main.Handler<? extends AbstractSpecialItem>>();

你可以在这里阅读super和extends之间的区别:Difference between <? super T> and <? extends T> in Java

相关问题