3

我被一个我不明白的愚蠢问题困住了。

class Foo<T extends Collection<E>, E> {
  private Class<T> collectionClass;
  private Class<E> elementClass;

  public Foo(Class<T> collectionClass, Class<E> elementClass) {
       this.collectionClass = collectionClass;
       this.elementClass = elementClass;
  }
} 

当我尝试运行它时

Foo<Collection<String>, String> foo = 
    new Foo<Collection<String>, String>(
        Collection.class,
        String.class);

我收到编译器错误

java.lang.Error: Unresolved compilation problem: 
The constructor Foo<Collection<String>,String>(Class<Collection>, Class<String>) is undefined

为什么 ?如果我删除泛型,没关系

Foo foo = 
    new Foo(
        Collection.class,
        String.class);

如果有人有一个想法,那就太好了,阻止我把头撞到墙上。

4

5 回答 5

4

没有Collection<String>.class, 是问题所在。您的选择包括

  • 不要使用反射;你为什么要使用反射?
  • 接受不安全演员表的需要
  • 使用各种工具之一在运行时引用泛型类型,例如 Guava 的TypeToken
于 2012-12-16T23:59:16.220 回答
1

您对此无能为力。只是围绕它

new Foo<Collection<String>, String>(
    (Class<Collection<String>>)(Class<?>)Collection.class,
    String.class);
于 2012-12-17T02:05:27.640 回答
0

没有运气,因为类型擦除,看到这个问题

然而,原始集合类和元素类可用于生成类型安全Collection<String>对象。所以去掉Collection中E的冗余,作为Collection。

于 2012-12-17T00:06:35.953 回答
0

对于您的用例,您可能可以放宽构造函数参数类型

public Foo(Class<?> collectionClass, Class<E> elementClass) 
{
    this.collectionClass = (Class<T>)collectionClass;
    this.elementClass = elementClass;
}

Foo<Collection<String>, String> foo = new Foo<>(Collection.class, String.class);

类型检查较少,因此用户必须确保没有传入错误的类,例如

Foo<Set<String>, String> foo = new Foo<>(List.class, String.class);
    ^^^                                  ^^^^
于 2012-12-17T00:06:47.023 回答
0

好的,

我看过其他人的答案,但不是最好的......

在 Oreilly Tiger 的书(第 5 版)(p167)中,他们做了一个非常明确的声明,即构造函数的签名中不能有通配符......

于 2012-12-17T00:19:13.047 回答