在Scala中,如果我們有一個類說斯卡拉Java的互操作性,與VAL
case class B(b: Int)
object B {
def main(args: Array[String] {
val b = B(1)
b.b = 2 // ** compile time error here **
}
}
會給出一個錯誤的說法,當scalac B.scala
error: reassignment to val
b.b = 2
^
一切編譯罰款是到這裏。
但是,如果我有一個Java類A.java
:
public class A {
public int a;
public A(int a) {this.a = a;}
public void setA(int a_) {this.a = a_;}
public String toString() {return "A: " + a;}
}
先用javac A.java
編譯它, 然後在斯卡拉與val
使用它:
object B {
def main(args: Array[String] {
val a = new A(1)
println("Before assignment: " + a)
a.a = 2 // ** No error here **
println("After assignment: " + a)
}
}
編譯B.scala
與scalac B.scala
與運行scala B
。沒有錯誤發生。
它在scala中打破val
的意向嗎?
如果我想在scala中使用java類時,維護實例a
的固定值,我該怎麼辦?
或者實際上有一些文件提到這種行爲?
Environment: Scala version 2.11.5 (OpenJDK 64-Bit Server VM, Java 1.7.0_75).
Centos 6.6
編輯
謝謝大家對您的回覆。
雖然我很清楚,通過使字段最終: public final int a;
,可以實現不變性。
我不希望通過修改java代碼來解決這個問題。 想象一下,我正在使用第三方Java庫,我無法修改他們的代碼,但我想確保我的代碼不會意外修改第三方的內部狀態,因此出現val
。
此外,通過使用javap -c
拆卸.class
文件,可以看出清楚,階不被插入到final
類B
使B.b
不可改變的。
也許有人解釋背後val
「神奇」將是您的Java類A
有用
您應該像這樣定義'b':'case class B(var b:Int)' –