我常想,private val
和private final val
一样,直到我在斯卡拉参考看到第4.1节:
常量值定义为以下形式
final val x = e
其中e是一个常量表达式(第6.24节)。final修饰符必须存在,并且不能给出类型注释。对常量值x的引用本身被视为常量表达式。在生成的代码中,它们将替换为定义的右侧e。
我写了一个测试:
class PrivateVal {
private val privateVal = 0
def testPrivateVal = privateVal
private final val privateFinalVal = 1
def testPrivateFinalVal = privateFinalVal
}
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 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #14 // Field privateVal:I
9: return
}
字节码就像Scala Reference所说的那样:private val
不是private final val
。
为什么不scalac只是把private val
作为private final val
?有什么根本原因吗?
注意,
—
康纳·道尔
private
作用域修饰符的语义与package private
Java中的相同。您可能要说private[this]
。
@ConnorDoyle:作为包私有吗?我不这么认为:
—
Make42 '16
private
意味着它仅仅是这一类,实例可见private[this]
只有这种情况下-除了相同的实例类,private
不允许任何人(来自同一个包包括)来访问值。
val
已经是不可变的,为什么我们final
在Scala中根本不需要关键字呢?为什么编译器不能将val
s与s一样对待final val
?