私はJava の相互運用性の問題と Scala ジェネリックとボクシング と同じ問題を抱えていますが、サードパーティのコードを変更する必要があるため、そこでの解決策がうまくいくとは思いません。
具体的には、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`
All that to say that when I finally get to extending MyScalaClass by writing MyJavaClass, I get
[ERROR] MyJavaClass.java:[11,8] MyJavaClass is not abstract and does not override abstract method result(com.twitter.util.Duration,com.twitter.util.Awaitable.CanAwait) in com.twitter.util.Awaitable
I figured I just have to implement result
for some reason, so I do, in MyJavaClass:
public void result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{}
Now I get
[ERROR] return type void is not compatible with scala.runtime.BoxedUnit
Changing my method to
public BoxedUnit result(com.twitter.util.Duration d,
com.twitter.util.Awaitable.CanAwait c)
{return BoxedUnit.UNIT;}
results in
[ERROR] return type scala.runtime.BoxedUnit is not compatible with void
なんてこった...それで、グーグルを始めます。ScalaジェネリックとボクシングによるJava相互運用性の問題への答えは、私の状況ではScalaがJavaと互換性のないバイトコードを生成し、Twitterクラスの一部を制御できれば問題を回避できると言っているようです(私はCloseAwaitablyと思います)ジェネリック化する元のメソッド実装で[U <: Unit]
、return ().asInstanceOf[U]
scalac をだまして「正確ではないユニット型」の可能性を認めさせます (ただし、これがどのように機能するかは完全にはわかりません)。
Twitter のクラスは制御できません。MyScalaClass と MyJavaClass だけです。メソッドについては実際には気にしません 。MyScalaClass で定義したいくつかの抽象メソッドを実装して、MyJavaClass から MyScalaClass を拡張できるようにしたいだけです。参考までに、私は Scala 2.10.4、JDK 1.8、および (twitter) util-core_2.10 6.22.0 を使用しています。最初の場所。MyScalaClass から継承する Scala クラスは、そのメソッドを実装する必要はなく、問題なくビルドされます。result
result
どうすればこれを回避できますか? 遊んでくれてありがとう。