【发布时间】:2014-12-25 21:45:37
【问题描述】:
假设我有这个 Scala 特征:
trait UnitThingy {
def x(): Unit
}
提供 Java 实现很简单:
import scala.runtime.BoxedUnit;
public class JUnitThingy implements UnitThingy {
public void x() {
return;
}
}
现在让我们从一个通用特征开始:
trait Foo[A] {
def x(): A
}
trait Bar extends Foo[Unit]
上述方法行不通,因为x 返回的单元现在已装箱,但解决方法很简单:
import scala.runtime.BoxedUnit;
public class JBar implements Bar {
public BoxedUnit x() {
return BoxedUnit.UNIT;
}
}
现在假设我在 Scala 端定义了 x 的实现:
trait Baz extends Foo[Unit] {
def x(): Unit = ()
}
我知道我在 Java 中看不到这个 x,所以我定义了自己的:
import scala.runtime.BoxedUnit;
public class JBaz implements Baz {
public BoxedUnit x() {
return BoxedUnit.UNIT;
}
}
但这会爆炸:
[error] .../JBaz.java:3: error: JBaz is not abstract and does not override abstract method x() in Baz
[error] public class JBaz implements Baz {
[error] ^
[error] /home/travis/tmp/so/js/newsutff/JBaz.java:4: error: x() in JBaz cannot implement x() in Baz
[error] public BoxedUnit x() {
[error] ^
[error] return type BoxedUnit is not compatible with void
如果我尝试抽象类,即代表到超级特征的技巧:
abstract class Qux extends Baz {
override def x() = super.x()
}
然后:
public class JQux extends Qux {}
情况更糟:
[error] /home/travis/tmp/so/js/newsutff/JQux.java:1: error: JQux is not abstract and does not override abstract method x() in Foo
[error] public class JQux extends Qux {}
[error] ^
(请注意,如果Baz 没有扩展Foo[Unit],JQux 的这个定义就可以正常工作。)
如果你看看javap 对Qux 的评价,你会觉得很奇怪:
public abstract class Qux implements Baz {
public void x();
public java.lang.Object x();
public Qux();
}
我认为Baz 和Qux 的问题必须是scalac 错误,但有解决方法吗?我并不真正关心Baz 部分,但是有什么方法可以从Java 中的Qux 继承?
【问题讨论】:
标签: java scala generics boxing