Java类中的Scala getter和setter

我想创建一个遵循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 xa = 1 

我得到“重新分配给val”错误消息。 我试图寻找这个,但是我发现从scala到java的另一个问题。

这样做的正确方法是什么?

谢谢!

你只能这样做,而你可能不想这样做很难。

不能做的是编写一个神奇的Java类,它被神奇地解释为Scala getter和setter。 原因是Scala将信息嵌入到其getter和setter所需的类文件中(例如,有零参数块或一个空参数块 – 这种区别在JVM(或Java)中没有保留)。

可以做的是使用Java来实现Scala定义的接口(即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> ja = 5 :8: error: reassignment to val ja = 5 

但由于它确实成功实现了特征,因此在输入特征时可以根据需要使用它:

 scala> (j: GetSetA).a = 5 (j: GetSetA).a: Int = 5 

所以这是一个混合包。 通过任何方式都不完美,但在某些情况下可能有足够的function来帮助。

(另一种选择当然是提供从Java类到具有引用Java类的实际方法的getter / setter的隐式转换;即使您不能从ScalainheritanceJava,这也是有效的。)

(编辑:当然没有关键的原因,编译器必须以这种方式行事;有人可能会认为解释Java定义的getter / setter对就好像它们是Scala那样(即如果类文件没有明确地说它来自Scala)是一个function增强的良好候选者,以提高Java互操作性。)

我怕你不能。 在Scala中,访问器必须是没有参数列表的方法,例如def a = _a 。 在Scala中编写例如def a() = _a会导致相同的错误,并且您无法在Java中定义没有参数列表的方法。 您可以通过生成自己的ScalaSignature来欺骗Scala编译器,但这可能不值得麻烦……