簡體   English   中英

Java類中的Scala getter和setter

[英]Scala getters and setters in Java class

我想創建一個遵循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的另一個問題。

做正確的方法是什么?

謝謝!

你只能這樣做,而你可能不想這樣做很難。

不能做的是寫一個神奇的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> 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的隱式轉換;即使您不能從Scala繼承Java,這也是有效的。)

(編輯:當然沒有關鍵的原因,編譯器必須以這種方式行事;有人可能會認為解釋Java定義的getter / setter對就好像它們是Scala那樣(即如果類文件沒有明確地說它來自Scala)是一個功能增強的良好候選者,以提高Java互操作性。)

我怕你不能。 在Scala中,訪問器必須是沒有參數列表的方法,例如def a = _a 在Scala中編寫例如def a() = _a會導致相同的錯誤,並且您無法在Java中定義沒有參數列表的方法。 您可以通過生成自己的ScalaSignature來欺騙Scala編譯器,但這可能不值得麻煩......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM