【发布时间】:2015-07-20 22:07:49
【问题描述】:
我遇到了与Java interoperability woes with Scala generics and boxing 相同的问题,但我认为那里的解决方案不适合我,因为它需要修改第三方代码。
具体来说,来自 Java(比如 MyJavaClass)我正在尝试扩展一个本身扩展 com.twitter.app.App 的 Scala 类 (MyScalaClass)。应用扩展了com.twitter.util.CloseAwaitably,而这又扩展了com.twitter.util.Awaitable。
Awaitable // trait where `result` is defined
^-CloseAwaitably // trait with some impl of `result`
^-App // trait with no mention of `result`
^-MyScalaClass // abstract class with no mention of `result`
^-MyJavaClass // just trying to get this guy to compile
// and it expects an impl of `result`
这就是说,当我最终通过编写 MyJavaClass 来扩展 MyScalaClass 时,我明白了
[ERROR] MyJavaClass.java:[11,8] MyJavaClass 不是抽象的,而是 不覆盖抽象方法 结果(com.twitter.util.Duration,com.twitter.util.Awaitable.CanAwait) 在 com.twitter.util.Awaitable
我认为出于某种原因我只需要实现 result,所以我在 MyJavaClass 中实现了:
public void result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{}
现在我明白了
[ERROR] 返回类型 void 与 scala.runtime.BoxedUnit 不兼容
改变我的方法
public BoxedUnit result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{return BoxedUnit.UNIT;}
结果
[ERROR] 返回类型 scala.runtime.BoxedUnit 与 void 不兼容
这到底是怎么回事……所以我开始用谷歌搜索。 Java interoperability woes with Scala generics and boxing 的答案似乎是说 Scala 在我的情况下生成了与 Java 不兼容的字节码,如果我控制了一些 Twitter 类,我可以解决这个问题(我认为 CloseAwaitably)在原始方法实现中使用[U <: Unit] 和return ().asInstanceOf[U] 对其进行泛化,以欺骗scalac 承认“某些不完全单位类型”的可能性(尽管我并不完全清楚它是如何工作的)。
我无法控制 Twitter 类,只有 MyScalaClass 和 MyJavaClass。 我实际上并不关心 result 方法 - 我只想能够从 MyJavaClass 扩展 MyScalaClass,实现我在 MyScalaClass 中定义的一些抽象方法。对于它的价值,我正在使用 Scala 2.10.4、JDK 1.8 和 (twitter) util-core_2.10 6.22.0,如果这是相关的:我真的不知道为什么它需要我实现 @首先是 987654333@。从 MyScalaClass 继承的 Scala 类不必实现该方法,并且构建得很好。
我该如何解决这个问题?感谢您的参与。
【问题讨论】:
-
难道你不能编写一个 Scala 包装类来转发你在 Java 类中提供的其他方法吗?
-
也许吧,但到目前为止我在这个方向上的努力都没有结果。尝试从 Scala 覆盖
result总是会导致error: method result overrides nothing.我已经尝试了我能想到的所有签名损坏。此外,出于某种原因,从任何 Scala 子类实现result不是必要,这让我怀疑正在发生一些不正常的事情。 -
这看起来不是应该从子类中覆盖
CloseAwaitably中的result吗?override def result(timeout: Duration)(permit: CanAwait): Unit = {super.result(timeout)(permit);}显然没有。 -
如果我从开头删除
override并尝试重新编译,我会得到name clash between defined and inherited member和...have same type after erasure而不是method result overrides nothing。
标签: java scala twitter interop twitter-util