【问题标题】:<T extends Enum<T>> T[] as a return type in Java 8<T extends Enum<T>> T[] 作为 Java 8 中的返回类型
【发布时间】:2023-04-02 15:48:01
【问题描述】:

我正在查看一些在 Java 7 中编译但在 Java 8 中编译失败的代码。

class Test {
    public <T extends Enum<T>> T[] doSomething(...) {...}

    public <T extends Enum<T>> T[] methodWhichCallsDoSomething() {
        ...
        return doSomething(...);
}

错误如下:

incompatible types: inference variable T has incompatible upper bounds java.lang.Enum<T>,T

我正在运行 jdk 1.8.0_71。

有谁知道让它在 Java 8 中编译和工作的解决方法或解决方案?

编辑:错误消息是为调用 doSomething() 的行给出的,用于括号之前的 col。

【问题讨论】:

  • 我想知道你为什么要这样做。如果你的代码中有多个方法使用同一个 T,为什么不把它放在类上呢?
  • 每个 Java 8 版本都能正常编译。也许问题出在... 部分。
  • 你是如何确保它针对每个版本编译的?
  • 我不会将此称为“更多信息”。当编译器拒绝你的方法调用时,它是否通过指向第一个 d 或最后一个 ) 或介于两者之间的某个位置来拒绝并不重要。关于您的另一个问题,我使用了一个贯穿所有 JDK 版本并编译指定代码的脚本对其进行了测试。
  • 如果doSomething的至少一个参数以任何方式引用了T,则methodWhichCallsDoSomething不可能提供正确的参数(除非都是null),因为没有适当的变量在范围内。由于编译器错误或未经检查的操作,很可能编译了代码,在任何一种情况下,这确实有可能发生了变化。像methodWhichCallsDoSomething() 这样的无参数方法承诺返回调用者希望的任何T[],无论如何都被破坏了。有几个类似反模式的例子,现在在 Java 8 下失败了。

标签: generics java-8


【解决方案1】:

问题是由您传递给doSomething 的内容引起的。您没有发布实际参数,但从签名中我们可以推断,如果doSomething 的至少一个参数以任何方式引用T,则methodWhichCallsDoSomething 不可能提供正确的参数(除非都是null),因为范围内没有合适的变量。

很可能由于编译器错误或未经检查的操作而编译了代码,在任何一种情况下,这种行为确实可能由于新的类型推断规则而发生了变化。

methodWhichCallsDoSomething() 这样承诺返回调用者希望的任何T[] 的无参数方法无论如何都被破坏了。有几个类似的反模式示例,现在在 Java 8 下失败了,例如 thisthis。如果这样的代码碰巧在早期版本中可以工作,那么它恰好可以工作,现在出现的问题实际上已经存在。

对于此类损坏的代码,现在出现编译器错误是更好的可能症状,因为有时代码仍然可以编译,但会在运行时突然中断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-16
    • 2014-04-03
    • 1970-01-01
    • 2011-11-09
    • 2012-01-22
    • 2020-08-22
    • 1970-01-01
    • 2015-08-21
    相关资源
    最近更新 更多