带有枚举参数类型的java泛型方法

时间:2017-05-17 18:14:56

标签: java enums

使用以下方法定义:

protected <T extends Enum<T>> Tuple4< Boolean, String, T, String> foo( T... args ) {
...
}

(即,接受任何类型的Enum作为参数的方法,在内部使用它并返回此类的实例)

并将其用作:

    protected String bar( Enum<?>... args ) {
...
        foo( args );
...

编译器抱怨:

error: method foo in class xxxx cannot be applied to given types;

但是,如果我改变“foo”声明,使用Enum而不是Enum,如:

protected <T extends Enum<?>> Tuple4< Boolean, String, T, String> foo( T... args ) {
...
}

一切都好了。

我不明白第一个错误的起源,这是编写此代码的最佳方式。

在“foo”中使用的术语“&lt; T extends Enum&lt; T&gt;&gt;&gt;” (递归总是让我有些怀疑的东西)或使用“&lt; T extends Enum&lt;?&gt;&gt;”吗

(注意:假设“bar”实现可以更改,但其声明无法更改。)

1 个答案:

答案 0 :(得分:2)

scope.setColor = function(key, color)中的?是通配符。您可以将其视为未知枚举。我们所知道的只是它是某种类型的枚举,但我们无法确定是什么类型。

另一方面,Enum<?>通用枚举。我们知道它是一个枚举,我们也知道它具体是Enum<T>类型。

通用枚举和未知枚举之间存在一些重要差异。例如,由于我们不知道未知枚举的类型,因此我们无法在T上使用add(someEnumVal)方法。这是因为我们永远无法确定列表中的枚举类型。但是,您可以在List<Enum<?>>上致电add(someEnumVal)(假设List<Enum<T>>类型为someEnumVal),因为我们可以确定该列表适用于{{1}类型的枚举}。

更好的选择?就个人而言,我更喜欢在通配符上使用泛型。但是,这意味着您必须能够将T方法修改为:

T