简体   繁体   English

具有泛型类的构造函数未定义

[英]Constructor with generic class is undefined

I'm stuck with a stupid problem I do not understand. 我遇到了一个我不明白的愚蠢问题。

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

When I try to run this 当我试图运行这个

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

I get a compiler error 我收到编译器错误

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

Why ? 为什么? If I erase generics, it's ok 如果我擦除泛型,那没关系

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

If somebody has an idea, it will be great and stop me to bang my head on wall. 如果有人有想法,那就太棒了,不要让我把头撞到墙上。

There is no such thing as a Collection<String>.class , is the problem. 没有Collection<String>.class这样的东西就是问题所在。 Your alternatives include 你的选择包括

  • don't use reflection; 不要使用反射; why are you using reflection? 你为什么用反射?
  • accept the need for an unsafe cast 接受不安全演员的需要
  • use one of the various tools for referring to generic types at runtime, such as Guava's TypeToken 使用各种工具之一在运行时引用泛型类型,例如Guava的TypeToken

There's not much you can do about it. 你无能为力。 Just cast around it 只是围绕它

new Foo<Collection<String>, String>(
    (Class<Collection<String>>)(Class<?>)Collection.class,
    String.class);

No luck, because of type erasure, see this question . 没有运气,因为类型擦除,请看这个问题

However a raw collection class and an element class may be used to generate a type safe Collection<String> object. 但是,原始集合类和元素类可用于生成类型安全的Collection<String>对象。 So remove the redundance of E in Collection, as Collection. 因此,删除集合中E的冗余,作为集合。

For your use case, you can probably relax constructor parameter type 对于您的用例,您可以放松构造函数参数类型

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

There's less type checking, so the user must make sure a wrong class is not passed in, like 类型检查较少,因此用户必须确保未传入错误的类,例如

Foo<Set<String>, String> foo = new Foo<>(List.class, String.class);
    ^^^                                  ^^^^

Ok, 好,

I have looked at other peoples' answers and not being the best at this... 我看过别人的答案而不是最好的......

In the Oreilly Tiger book (for version 5) (p167), they make a very explicit statement that a constructor CAN NOT have a wildcard in it's signature... 在Oreilly Tiger书中(对于第5版)(p167),他们做了一个非常明确的陈述,即构造函数在其签名中不能有通配符......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM