我想创建一个遵循Scala setters / getters惯例的Java类。
我尝试过简单的类,但它不起作用:
public class JavaA {
private int a = 0;
public int a() {
return a;
}
public void a_$eq(int a) {
this.a = a;
}
}
但是当我尝试从scala访问它时:
val x = new JavaA
x.a = 1
我收到“重新分配给val”错误消息。我试图寻找这个,但是我发现了从scala到java的另一个问题。
这样做的正确方法是什么?
谢谢!
答案 0 :(得分:13)
你只能这样做,而且你可能不想做到这一点很难。
你无法做的事情就是编写一个神奇的Java类,它被神奇地解释为Scala getter和setter。原因是Scala将信息嵌入到其getter和setter所需的类文件中(例如,有零参数块或一个空参数块 - 这种区别在JVM(或Java)中没有保留)。 / p>
可以做的是使用Java来实现Scala定义的接口(即特征): 所做的事情,即便如此,也是直接使用该类(再次因为Java没有为Scala添加适当的注释信息): 但由于 成功实现了特征,因此在输入特征时可以根据需要使用它: 所以它很混合。通过任何方式都不完美,但在某些情况下可能有足够的功能来帮助。 (另一种选择当然是提供从Java类到具有引用Java类的实际方法的getter / setter的隐式转换;即使你不能拥有它也能工作Java继承自Scala。) (编辑:当然没有关键的原因,编译器必须以这种方式行事;有人可能会认为解释Java定义的getter / setter对就好像它们是Scala那样(即如果类文件没有明确地说它来自Scala,那么它就是改进Java互操作性的一个很好的候选者。)// GetSetA.scala
trait GetSetA { def a: Int; def a_=(a: Int): Unit }
// JavaUsesGSA.java
public class JavaUsesGSA implements GetSetA {
private int a = 0;
public int a() { return a; }
public void a_$eq(int a) { this.a = a; }
}
scala> j.a = 5
<console>:8: error: reassignment to val
j.a = 5
scala> (j: GetSetA).a = 5
(j: GetSetA).a: Int = 5
答案 1 :(得分:1)
我怕你不能。在Scala中,访问器必须是没有参数列表的方法,如def a = _a
。写作例如Scala中的def a() = _a
会导致相同的错误,并且您无法在Java中定义没有参数列表的方法。您可以通过生成自己的ScalaSignature
来欺骗Scala编译器,但这可能不值得麻烦......