【问题标题】:Why does LongProperty implement Property<Number> but not Property<Long>?为什么 LongProperty 实现了 Property<Number> 而不是 Property<Long>?
【发布时间】:2016-01-05 20:21:31
【问题描述】:

我在 JavaFX API 中发现了一个似乎很特殊的东西:LongProperty 实现了 Property&lt;Number&gt;,但不是 Property&lt;Long&gt;

这是什么原因?我有点理解这一切都源于 Java 固有的协变和逆变问题,因为泛型通过擦除实现愚蠢,以保持与字节码的向后兼容性;但是让LongProperty 同时实现Property&lt;Number&gt; Property&lt;Long&gt; 会出现什么问题?

编辑:这个问题源于这个问题:Apply LongProperty to TableColumn programmatically (vs semantically)

【问题讨论】:

  • 嗯...我想我可能是太仓促了,没有完全理解Java的协变和逆变,所以它可能根本不是问题。很抱歉。
  • (这里不假设答案 - 只是对@sillyfly的一个问题)。 Long 是 Number 的一个子类,所以它不是通过它的父类固有地实现的——也许只需要一个演员表?
  • 我认为这是一个错误。设计应该类似于abstract class NumberProperty&lt;N extends Number&gt; implements Property&lt;N&gt;,然后是class IntegerProperty extends NumberProperty&lt;Integer&gt; 等。
  • 这可能与Property 方法的使用方式有关。像这样的东西可以作为一个特性而不是一个错误存在,以允许更宽松的使用。请注意,它的其他超级接口以long 的形式提供访问权限。
  • @Radiodef 嗯,是的,但是现在你可以这样做 LongProperty lp = new SimpleLongProperty();DoubleProperty dp = new SimpleDoubleProperty(); dp.bindBidirectional(lp); dp.set(1.5);,现在你有了 dp.getValue().equals(lp.getValue()) == false,即使它们是双向绑定的。如果他们没有这样做的话,API 中的不一致性比缺乏灵活性更糟糕。 (请记住,您仍然可以实例化SimpleObjectProperty&lt;Number&gt;,因此您可以使用该机制绑定包含任何类型数字的可观察对象。)

标签: java generics javafx


【解决方案1】:

不能同时实现。

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

bindBidirectional(Property<Long> other) { ... }

在底层,擦除意味着它被编译为:

bindBidirectional(Property other) { ... }

那么,实现Property&lt;Number&gt;Property&lt;Long&gt; 的东西会做什么呢?它有两种方法:

bindBidirectional(Property<Long> other) { ... }
bindBidirectional(Property<Number> other) { ... }

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

bindBidirectional(Property other) { ... }
bindBidirectional(Property other) { ... }

这两种方法有冲突,运行时无法解决。

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

Property rawLongProperty = new LongProperty();
rawLongProperty.bindBidirectional(someOtherRawProperty);

没有办法知道这要解析为两个bindDirectional 变体中的哪一个。

【讨论】:

  • @yshavit 但是你真的希望能够做到LongProperty lp ;DoubleProperty dpdp.bindBidirectional(lp)吗?这似乎不是好的 API...
  • @sillyfly 不,我的意思是它只能实现一个Property&lt;Something&gt;。那东西可以是它想要的任何东西——对象、长整数、数字等等——但它也不能实现Property&lt;SomethingElse&gt;
  • @yshavit 是的,很公平。 (注意,不是我的问题。)但这是一个设计缺陷:)。
  • 我已经发布了一个具体的问题:stackoverflow.com/questions/34621485/…
猜你喜欢
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多