我曾经认为private val并且private final val相同,直到我在Scala参考中看到4.1节:
形式是常量值定义
Run Code Online (Sandbox Code Playgroud)final val x = e其中e是常数表达式(§6.24).必须存在最终修饰符,并且不能给出类型注释.对常量值x的引用本身被视为常量表达式; 在生成的代码中,它们被定义的右侧e替换.
我写了一个测试:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
Run Code Online (Sandbox Code Playgroud)
javap -c 输出:
Compiled from "PrivateVal.scala"
public class PrivateVal {
public int testPrivateVal();
Code:
0: aload_0
1: invokespecial #19 // Method privateVal:()I
4: ireturn
public int testPrivateFinalVal();
Code:
0: iconst_1
1: ireturn
public PrivateVal();
Code:
0: aload_0
1: invokespecial #24 …Run Code Online (Sandbox Code Playgroud) 在Java中,当跨多个线程(通常)使用对象时,最好将字段设为final.例如,
public class ShareMe {
private final MyObject obj;
public ShareMe(MyObject obj) {
this.obj = obj;
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,obj的可见性将在多个线程中保持一致(假设obj具有所有最终字段),因为它是使用final关键字安全构造的.
在scala中,它不会出现val编译到最终引用,而是val是scala中的语义,阻止您重新分配变量(构造函数中的Scala最终变量).如果scala构造函数变量未定义为final,它们是否会遇到同样的问题(在actor中使用这些对象时)?