使用以下方法定义:
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”实现可以更改,但其声明无法更改。)
答案 0 :(得分:2)
scope.setColor = function(key, color)
中的?
是通配符。您可以将其视为未知枚举。我们所知道的只是它是某种类型的枚举,但我们无法确定是什么类型。
另一方面,Enum<?>
是通用枚举。我们知道它是一个枚举,我们也知道它具体是Enum<T>
类型。
通用枚举和未知枚举之间存在一些重要差异。例如,由于我们不知道未知枚举的类型,因此我们无法在T
上使用add(someEnumVal)
方法。这是因为我们永远无法确定列表中的枚举类型。但是,您可以在List<Enum<?>>
上致电add(someEnumVal)
(假设List<Enum<T>>
类型为someEnumVal
),因为我们可以确定该列表适用于{{1}类型的枚举}。
更好的选择?就个人而言,我更喜欢在通配符上使用泛型。但是,这意味着您必须能够将T
方法修改为:
T