【问题标题】:Subclass generics in hash maps?哈希映射中的子类泛型?
【发布时间】:2013-06-16 07:39:08
【问题描述】:
 public class people {

}

class friend extends people {

}

class coworkers extends people {

}

class family extends people {

}

public void fillMaps(){
    ConcurrentMap<String, Collection<family>> familyNames = new ConcurrentHashMap<String, Collection<family>>();
    ConcurrentMap<String, Collection<coworkers>> coworkersNames = new ConcurrentHashMap<String, Collection<coworkers>>();
    ConcurrentMap<String, Collection<friend>> friendNames = new ConcurrentHashMap<String, Collection<friend>>();
    populateMap(family.class, familyNames);
    populateMap(coworkers.class, coworkersNames);
    populateMap(friend.class, friendNames);
}

private <T> void populateMap(Class<T> clazz, ConcurrentMap<String, Collection<people>> map) {
        if (clazz == family.class) {
            map.put("example", new ArrayList<family>());
        }
        if (clazz == coworkers.class) {
            map.put("example", new ArrayList<coworkers>());
        }
        if (clazz == friend.class) {
            map.put("example", new ArrayList<friend>());
        }

}

family、coworkers 和friend 类都是从称为people 的超类扩展而来的。为什么下面的方法不允许我将类用作 populateMap 方法的参数的参数。另外,为什么它不允许我在这里传递子类集合作为参数?

error:
The method populateMap(Class<T>, ConcurrentMap<String,Collection<people>>) is not applicable for the arguments (Class<family>, ConcurrentMap<String,Collection<family>>)

【问题讨论】:

  • 错误说明了什么?

标签: java generics collections arraylist


【解决方案1】:

因为,ArrayList&lt;family&gt; 不被视为Collection&lt;people&gt; 的子类型,因此无法分配。 Polymorphism 的概念并没有像它们对类一样扩展到 Java 泛型。

private <T> void populateMap(ConcurrentMap<String, Collection<T>> map) {
    map.put("example", new ArrayList<T>());
}

【讨论】:

  • 有办法解决这个问题吗?
  • 为什么不呢? ArrayList 实现 Collection。如果是这样,map.put 也会失败。
  • @m0skit0 是 ArrayList 可以,但 ArrayList 不能分配给 Collection。 ArrayList 另一方面可以。编译器认为它们不同以保护集合,因为该类型在运行时不可用(由于类型擦除)。
【解决方案2】:

ArrayList&lt;family&gt; 不被视为Collection&lt;people&gt; 的子类型 ArrayList&lt;family&gt; Collection&lt;family&gt; 的子类型 ArrayList&lt;people&gt;Collection&lt;people&gt; 的子类型

你想要这个

private <T extends people> void populateMap(ConcurrentMap<String, Collection<T>> map) {

                map.put("example", new ArrayList<T>());


    }

【讨论】:

  • 它消除了 fillMaps() 内部的错误。但现在我看到 map.put 部分有错误。它说:'code'Map> 类型中的 put(String, Collection) 方法不适用于参数 (String, ArrayList)'code'
  • 类参数不用传。
  • private &lt;T extends people&gt; void populateMap 准确地说:)
  • 为什么我们不需要传递类参数?
  • 在泛型中,T 的类型将取决于作为参数传递的 T 的值
【解决方案3】:

使用

private <T> void populateMap(Class<T> clazz, ConcurrentMap<String, Collection<? extends people>> map) {
...
}

Collection&lt;family&gt; 应该对 Collection&lt;? extends people&gt; 有效,因为 family 扩展了 people。但这可能不是您想要的,Rahul 的答案可能是您想要的。

【讨论】:

  • 不,这也编译失败。
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 2011-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 2012-01-31
相关资源
最近更新 更多