Java泛型字段类型不能像泛型方法类型那样具体化吗?

8

我有一些4年前为Java 5编写的旧命令行参数解析代码,由于泛型处理方式和/或某些库类是否通用的更改,它在Java 6中无法编译。在尝试修复它时,我遇到了以下问题;因为我已经有4年没有接触Java了,而且我从一开始就不是泛型专家,所以这个问题让我有点困扰。

该库允许我指定某些命令行选项对应枚举类型。为此,对应于此选项的ArgumentSpecification对象想要保存一个Class对象,我们将其称为“enumClass”,对应于枚举类。不幸的是,我似乎无法弄清楚如何正确编写该字段的类型,以将其限制为包含对应于实际Enum类的类对象。我认为我想要的是像这样的东西:

protected <E extends Enum<E>> Class<E> enumClass; // compiler error

但编译器在这方面有点问题。另一方面,如果指定返回值和/或参数的方法,编译器则完全满意:

protected <E extends Enum<E>> Class<E> dummyTest(Class<E> foo) { return foo; } // "works"

我可以尝试使用这个字段代替:
protected Class<? extends Enum<?>> enumClass;

但是这并不起作用...代码的其他部分需要"<E extends Enum<E>>""类型,以便它们可以实际获取E,而这似乎与"<? extends Enum<?>>"不匹配,因为我会得到这样的编译器错误:

Bound mismatch: The generic method checkedEnumFromString(Class<E>, String) of type EnumUtil is not applicable for the arguments 
 (Class<capture#1-of ? extends Enum<?>>, String). The inferred type capture#1-of ? extends Enum<?> is not a valid substitute for the bounded 
 parameter <E extends Enum<E>>

这里有没有我错过的声明具有正确类型的字段的方法?如果有,是什么?如果没有,那Java能够在方法中声明类型但不能在字段中声明类型,难道不是严重的问题吗?或者我是否如此混乱以至于我的问题根本没有意义?

2个回答

9
如果您需要像这样定义带有显式参数E的字段,则可能需要对声明该字段的类型进行参数化。编译以下代码类似于此:
class MyClass<E extends Enum<E>> {
    Class<E> enumClass;
}

2
我很害怕...... 唉。我认为在我的情况下,接受Java的类型系统是愚蠢的(感谢类型擦除!)并且与自由撒上@ShutTheHellUp("unchecked")相结合使用“Class enumClass;”实际上会更少的不当之处。不过还是感谢您的回复。 - Scott Davies

7

您正在尝试声明一个“通用字段”——它本身具有类型参数。在Java中没有这样的概念——只有方法和类型可以引入类型参数。

如polygenelubricants所说,您可以在类型本身中引入额外的类型参数,并将其用作字段的类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接