为什么 LongProperty 实现 Property<Number> 而不是 Property<Long>?

Ita*_*tai 3 java generics javafx

我在 JavaFX API 中遇到了一个看似特殊的问题:LongPropertyimplements Property<Number>,但不是Property<Long>。

这是什么原因呢?我觉得这一切都源于 Java 固有的协变和逆变问题,因为泛型通过擦除来愚蠢地实现,以保持与字节码的向后兼容性;LongProperty但是同时实施Property<Number> 和 会出现什么问题Property<Long>呢?

编辑:这个问题源于这个问题:Apply LongProperty to TableColumnprogrammatically (vs语义地)

ysh*_*vit 5

它无法同时实现两者。

为此,需要在使用泛型的接口中实现每个方法的两个版本。我们以一个为例:

bindBidirectional(Property<Long> other) { ... }
Run Code Online (Sandbox Code Playgroud)

在幕后,擦除意味着它被编译为:

bindBidirectional(Property other) { ... }
Run Code Online (Sandbox Code Playgroud)

那么,它会实现什么Property<Number>并Property<Long>做什么呢?它有两种方法:

bindBidirectional(Property<Long> other) { ... }
bindBidirectional(Property<Number> other) { ... }
Run Code Online (Sandbox Code Playgroud)

...这将在擦除后编译为两种方法:

bindBidirectional(Property other) { ... }
bindBidirectional(Property other) { ... }
Run Code Online (Sandbox Code Playgroud)

这两个方法是冲突的,并且在运行时没有办法解决它们。

即使您使用了一些编译器技巧来解决这个问题,当有人使用 LongProperty 作为原始属性时会发生什么?

Property rawLongProperty = new LongProperty();
rawLongProperty.bindBidirectional(someOtherRawProperty);
Run Code Online (Sandbox Code Playgroud)

无法知道bindDirectional这要解决两个变体中的哪一个。

  • 这是[错误数据库中对此的讨论](https://bugs.openjdk.java.net/browse/JDK-8125218) (3认同)