【发布时间】:2022-01-18 12:15:55
【问题描述】:
我目前真的无法理解这里发生的事情。我有以下(最少的)代码:
public class SillyCast {
interface B {}
interface D<T extends B> {}
class C<T extends D<?>> {}
class A<T extends B> extends C<D<T>> {}
List<Class<? extends C<?>>> list = new ArrayList<>();
void m() {
list.add((Class<? extends C<?>>) A.class);
}
}
在 Eclipse 中编译(和运行)此代码时,一切都按预期工作,但从命令行(Oracle JDK)执行时,编译期间出现以下错误:
error: incompatible types: Class<A> cannot be converted to Class<? extends C<?>> list.add((Class<? extends C<?>>) A.class);
我知道 Oracle JDK 的行为并不总是与 Eclipse JDT 完全相同,但这似乎很奇怪。
如何将A.class 的实例添加到我的 ArrayList 中? 直觉上看来这应该是可能的。
为什么 Oracle JDK 和 Eclipse JDT 对这个演员表有不同的看法?为什么 Oracle JDK 在执行此转换时遇到问题。
起初我认为这可能是一个错误,但我在不同的 Java 版本(8 和 11)上对此进行了测试,并且问题发生在所有版本上。此外,这种类型的演员表似乎太“简单”了,因为这可能会在多个版本中被忽视,所以希望这可以通过设计来完成。
【问题讨论】:
-
我在 intellij
java: incompatible types中遇到编译错误。你在做什么似乎有点奇怪 - 创建接口 B,创建由 B 的子类参数化的接口 D(因此它由扩展 B 的接口参数化,但它不是 B 本身的子类)然后你创建 2 个由接口的子类参数化的静态类(顺便说一句:info)?这非常令人困惑,您要实现什么目标?可能有一个非常简单的解决方案,不需要这种过度工程。记住亲吻:D -
Eclipse 4.22 为最终的
list.add提供了“未经检查的演员表”警告,所以它并不是真的很开心。 -
static List<Class<? extends C>> list = new ArrayList<>();这个列表的定义可以正常工作。这对你有用吗?任何其他信息都会有所帮助,这是一个非常有趣的挑战。 -
@ferrouskid 静态只是为了使最小的示例可以运行。可能只是忽略了静态,因为我的实际代码无论如何都没有它们。我更新了代码,使其不需要静态。 > 这太令人困惑了,你想达到什么目的?我知道这个例子在这个最小的形式下看起来很傻,但这是生产代码的减少,它将它扩展到多个类和数千行代码。我刚刚创建了这个以将问题减少到易于阅读的最小形式。
-
@ferrouskid 该示例来自(继承的)非常复杂的生产代码,多年来一直在使用并且肯定可以正常工作。我刚刚发现它是因为我们出于部署原因需要更改 JDK。
标签: java eclipse generics compiler-errors eclipse-jdt