我遇到了与 Scala generics 和 boxing的 Java 互操作性问题相同的问题,但我认为那里的解决方案对我不起作用,因为它需要修改第三方代码。
具体来说,从 Java(比如 MyJavaClass)我试图扩展一个本身扩展com.twitter.app.App的 Scala 类(MyScalaClass) 。App 扩展了 com.twitter.util.CloseAwaitable,而这又扩展了 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 时,我明白了
[错误] MyJavaClass.java:[11,8] MyJavaClass 不是抽象的,并且不会覆盖 com.twitter.util.Awaitable 中的抽象方法 result(com.twitter.util.Duration,com.twitter.util.Awaitable.CanAwait)
我想我只是出于某种原因必须实现result
,所以我在 MyJavaClass 中实现了:
public void result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{}
现在我明白了
[错误] 返回类型 void 与 scala.runtime.BoxedUnit 不兼容
将我的方法更改为
public BoxedUnit result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{return BoxedUnit.UNIT;}
结果是
[错误] 返回类型 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,如果这是相关的:我真的不知道为什么它需要我result
在第一名。从 MyScalaClass 继承的 Scala 类不必实现该方法,并且构建得很好。
我怎样才能解决这个问题?感谢参与。