Java类中的Scala getter和setter [英] Scala getters and setters in Java class

查看:132
本文介绍了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的另一个问题。



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



谢谢!

解决方案

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



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

可以做的是使用Java实现Scala定义的接口(即特征):

  // GetSetA.scala 
trait GetSetA {def a:Int; def a _ =(a:Int):Unit}

// JavaUsesGSA.java
公共类JavaUsesGSA实现GetSetA {
private int a = 0;
public int a(){return a; }
public void a_ $ eq(int a){this.a = a; }
}

无法做什么,甚至所以,直接使用该类(再次因为Java没有为Scala添加适当的注释信息):

  scala> ja = 5 
< console>:8:错误:重新分配给val
ja = 5

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

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

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



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



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


I would like to create a Java class that follows the Scala setters/getters convention.

I tried following simple class, but it does not work:

public class JavaA {
private int a = 0;

public int a() {
    return a;
}

public void a_$eq(int a) {
    this.a = a;
}
}

But when I try to access it from scala:

val x = new JavaA
x.a = 1

and I get "reassignment to val" error message. I tried to look for this, but all issues I found where the other way around from scala to java.

What is the right way to do it?

Thanks!

解决方案

You can only sort of do this, and it's hard enough that you probably don't want to.

What you can't do is write a bare Java class that magically is interpreted as Scala getters and setters. The reason is that Scala embeds information into the class file that it requires for its getters and setters (e.g. are there zero parameter blocks or one empty parameter block--a distinction which is not preserved on the JVM (or in Java)).

What you can do is use Java to implement a Scala-defined interface (i.e. 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; }
}

What you can't do, even so, is use the class directly (again because Java does not add the appropriate annotation information for Scala):

scala> j.a = 5
<console>:8: error: reassignment to val
       j.a = 5

but since it does implement the trait successfully, you can use it as desired when it is typed as the trait:

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

So it's rather a mixed bag. Not perfect by any means, but it may be sufficiently functional to help out in some cases.

(The other alternative, of course, is to provide an implicit conversion from the Java class to one that has a getter/setter that references the real methods on the Java class; this works even when you can't have the Java inherit from Scala.)

(Edit: Of course there's no critical reason that the compiler must act this way; one could argue that interpreting Java-defined getter/setter pairs as if they were Scala ones (i.e. if the classfile does not explicitly say it's from Scala) is a good candidate for a feature enhancement to improve Java interoperability.)

这篇关于Java类中的Scala getter和setter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆