【问题标题】:java generic method with enum parameter type具有枚举参数类型的java泛型方法
【发布时间】:2017-05-17 18:14:56
【问题描述】:

使用以下方法定义:

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”中使用术语“>”(递归的东西总是让我有些怀疑)或使用“>”有什么区别?

(注意:假设“bar”的实现可以改变,但它的声明不能改变)。

【问题讨论】:

  • 阅读泛型与通配符的主题,我相信这与传递给fooargs 是根据Enum&lt;?&gt; 而不是@ 定义的事实有关987654328@
  • 你正在处理一个枚举类型“?”和一个枚举类型“T”。它们不一样,这就是为什么你会得到基于类型的错误
  • @Rocket6488: 是的,这是新的坏消息,哪个是好消息?
  • 根据您制定的规则,您必须将可更改的定义更改为可更改的定义

标签: java enums


【解决方案1】:

Enum&lt;?&gt; 中的 ? 是通配符。您可以将其视为一个未知枚举。我们所知道的只是它是某种类型的枚举,但我们无法确定是什么类型。

另一方面,Enum&lt;T&gt; 是一个通用枚举。我们知道它是一个枚举,而且我们也知道它是特定类型的 T

通用枚举和未知枚举之间有一些重要的区别。例如,由于我们不知道未知枚举是什么类型,我们不能在List&lt;Enum&lt;?&gt;&gt; 上使用方法add(someEnumVal)。这是因为我们永远无法确定列表中的枚举类型。但是,您可以在 List&lt;Enum&lt;T&gt;&gt; 上调用 add(someEnumVal)(假设 someEnumVal 的类型为 T),因为我们可以确定该列表适用于 T 类型的枚举。

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

protected <T extends Enum<T>> String bar( T... args ) {

【讨论】:

  • "声明不能更改"
  • 感谢您的回答。修改“bar”声明的问题是我还必须修改“bar”的调用者和调用者的调用者等等。一般来说,总是将“.... ( ... Enum> ... )”替换为“... > ... ( ... T ...)”。您认为在 foo(编译的选项)中使用“>”会产生任何问题吗?
  • 是的,它会产生问题。类型断言需要仔细考虑,而不是对语法选项投掷飞镖。为什么层层调用共享相同的参数类型?这是一个架构缺陷,需要修复,而不是解决。 (得墨忒耳法则)&lt;T extends Enum&lt;T&gt;&gt; 答案是正确答案。不要为了保留错误而丢弃它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多