我想创建一个遵循 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 的相反方向。
正确的做法是什么?
谢谢!
最佳答案
你只能这样做,而且它已经够难了,你可能不想这样做。
您不能做的是编写一个神奇地解释为 Scala getter 和 setter 的裸 Java 类。原因是 Scala 将信息嵌入到它的 getter 和 setter 所需的类文件中(例如,是否有零个参数 block 或一个空参数 block ——JVM(或 Java)中未保留的区别)。
您可以做的是使用 Java 实现 Scala 定义的接口(interface)(即 trait):
// 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; }
}
即便如此,您不能做的是直接使用该类(同样是因为 Java 没有为 Scala 添加适当的注释信息):
scala> j.a = 5
<console>:8: error: reassignment to val
j.a = 5
但由于它确实成功地实现了特征,所以当它被键入为特征时,您可以根据需要使用它:
scala> (j: GetSetA).a = 5
(j: GetSetA).a: Int = 5
所以这是一个混合包。无论如何都不完美,但在某些情况下它可能足以提供帮助。
(当然,另一种选择是提供从 Java 类到具有引用 Java 类上实际方法的 getter/setter 的类的隐式转换;即使您没有 Java继承自 Scala。)
(编辑:当然没有关键的理由编译器必须以这种方式行事;有人可能会争辩说,解释 Java 定义的 getter/setter 对就好像它们是 Scala 的一样(即,如果类文件没有明确说它来自 Scala)是一个很好的功能增强候选者,以提高 Java 互操作性。)
关于java - Java 类中的 Scala getter 和 setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10897307/