混淆Java泛型用法:如何正确参数化?

时间:2010-03-05 02:17:24

标签: java generics inheritance

我正在查看这种形式的代码:


     1  package com.stackoverflow.java.questions;

     2  import java.util.ArrayList;
     3  import java.util.List;

     4  public class B extends A<B> {
     5      
     6      private
     7      <C extends A>
     8      List<C> getList(Class<C> cls) {
     9          
    10          List<C> res = new ArrayList<C>();

                 // "snip"... some stuff happening in here, using cls

    11          return res;
    12      }

    13      public
    14      List<A> getList() {
    15          return getList(A.class);
    16      }

    17  }

    18  abstract class A<C extends A<C>> {

    19  }


是的,我知道这很难看,但我尽可能地减少了它。

我的问题是如何正确地参数化第7,14和15行的A?

目前,我从Eclipse获取第7和第14行的警告(A是原始类型。应该参数化通用类型A的参考)。我怀疑,一旦我修复了其他两个,我会得到第15行的一个,但我不确定。无论哪种方式,它目前都没有参数化,可能应该是,但我不知道语法应该是什么。

有关如何添加正确的参数语义和语法以摆脱这些警告的任何想法?

注意:我不确定A是否是递归泛型是否重要。如果我只是使用“抽象类A {}”代替其当前定义,我仍会得到相同的警告。

老实说,如果这是我自己的代码,我会把它变成一件简单的事情。不幸的是,它是API的一部分,所以我试图尽可能少地改变它。

谢谢!

更新:

我能够通过参数化来解决警告问题,但是会以错误为代价。归结于此,我如何得到一个类&lt; A&lt; B&gt;&gt;从抽象类?

类似的东西,

类&LT; A&LT B个;&GT; cls = A.class;

但是,这会导致类型不匹配错误。

更新,第2部分:

事实证明,由于类型擦除,你无法做到这一点。请参阅我的其他问题here.

3 个答案:

答案 0 :(得分:4)

您可以在前两个实例中使用<C extends A<B>>List<A<B>>开始。在这种情况下,传递类型键会适得其反(请参阅永远不会使用cls参数),所以,只需将其删除即可。

(你总是可以说B.<Foo>getList()使用特定的类型对其进行专门实例化,假设你很高兴当然没有这种类型。)


更新以合并OP的编辑:使用A<?>是否适用于您的代码?在有限的情况下,您可能不需要完全指定类型。不幸的是,我没有您的代码,因此只有您可以了解它是否有用。

答案 1 :(得分:0)

你到底在做什么cls:

// "snip"... some stuff happening in here, using cls

根据您在此处所做的操作,您可以使用Type实例替换Class实例,如果您告诉我更多关于您在此处执行的操作,我可能会为您提供一个替代解决方案,以使其正常工作。< / p>

答案 2 :(得分:0)

事实证明,由于类型擦除,你无法做到这一点。在这里查看我的其他问题: Java: how do I get a class literal from a generic type?