【问题标题】:Java generic methods: super can't be used?Java泛型方法:super不能用?
【发布时间】:2011-12-06 16:39:29
【问题描述】:

所以我有这个方法:

protected void collectSelectedItems(ListSelectionModel lsm, 
         Collection<? super MyItemClass> result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
}

我想返回集合而不是使用 void 方法:

protected <T super MyItemClass> Collection<T> 
  collectSelectedItems(ListSelectionModel lsm, Collection<T> result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
    return result;
}

打算做这样的事情(MyItemClass extends MyItemBaseClass):

List<MyItemBaseClass> list = 
   collectSelectedItems(lsm, new ArrayList<MyItemBaseClass>());

但我在super 上遇到语法错误:

令牌“super”的语法错误,预期

什么给了?我可以解决这个问题吗?

【问题讨论】:

  • 错误说明了什么?
  • 你想如何调用它?
  • ObjectMyItemClass 的超级,所以Collection 可以是Collection&lt;Object&gt;。我不认为你可以在这里使用super
  • SLaks,Kerrek:刚刚编辑答案以解决您的问题。
  • 彼得,为什么不呢? PECS:我传递了 MyItemClass 的 C消费者,因此我需要使用 super 而不是 extends

标签: java generics bounded-wildcard


【解决方案1】:

这里有一个链接解释了为什么不允许这样做:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

它基本上只是说在类型参数中使用 super“不会给你买任何东西”,因为如果允许这样做,擦除可能只会将其擦除到 Object,这没有多大意义。

【讨论】:

  • 如果你想声明你的方法采用Comparator&lt;? super Widget&gt;,它“给你买东西”,因为Comparator&lt;Object&gt; 完全能够对Object 的所有子类进行排序。但是,是的,对于收藏,这几乎总是错误的做法。
  • 这不是链接页面所说的 - 它明确表示如果在 method 声明中允许 super ,这将有助于创建类型安全的泛型方法。现在我碰到的例子是 Optional 的 orElse:它只接受与 Optional 相同的类型,尽管说 Optional&lt;Subtype&gt; optional = ...; Supertype result = optional.orElse(supertypeInstance);
【解决方案2】:

好吧,我没有准确回答我的问题,但对于我的问题,这是一个可以接受的解决方案:

protected <T extends Collection<? super MyItemClass>> 
  T collectSelectedItems(ListSelectionModel lsm, T result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
    return result;
}

【讨论】:

    【解决方案3】:

    这里有两个想法。第一个只返回一个通用的Collection,第二个返回实际的result-type:

    public <T, S extends T> Collection<T> ver1(Collection<S> src, Collection<T> dst)
    {
        dst.addAll(src);
        return dst;
    }
    
    public <U, T extends Collection<U>, S extends U> T ver2(Collection<S> src, T dst)
    {
        dst.addAll(src);
        return dst;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多