有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAVAutil。使用各种泛型类对象映射

我喜欢java。util。映射,其中包含不同的泛型类对象。在我的案例处理程序中,例如:

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
 }
}

和另一个实现处理程序的类

对于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);

但是,我无法通过添加不同的处理程序实现来创建映射,例如:

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总是说这些值不适用于地图。 我认为这种行为是有效的,并试图更好地理解泛型和PECS原则(通过网络和一些书籍查看)。但我还是不明白,要找出解决办法。我有处理程序类及其特殊的泛型类型,并且能够使用方法(编码、解码)以及创建处理程序的映射


共 (2) 个答案

  1. # 1 楼答案

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

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

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

  2. # 2 楼答案

    如果使用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>());
      }
    }