【发布时间】:2013-09-08 13:00:12
【问题描述】:
私有 var 构造函数参数和没有 val/var 的构造函数参数有什么区别?它们在范围/可见性方面是否相同?
例如:
class Person(private var firstName:String, lastName:String)
【问题讨论】:
标签: scala scala-2.10
私有 var 构造函数参数和没有 val/var 的构造函数参数有什么区别?它们在范围/可见性方面是否相同?
例如:
class Person(private var firstName:String, lastName:String)
【问题讨论】:
标签: scala scala-2.10
是的,有两个重要的区别。首先是简单的:没有var 或val 关键字的构造函数参数不是可变变量——它们的值不能在类的主体中更改。
即使我们将自己限制为val 关键字,private val 和无关键字参数之间仍然存在差异。考虑以下几点:
class Person(private val firstName: String, lastName: String)
如果我们查看带有javap -v Person 的编译类,我们会看到它只有一个字段,即firstName。 lastName 只是一个构造函数参数,这意味着它可能在类初始化后被垃圾回收等。
编译器足够聪明,可以知道在初始化后何时需要lastName 的值,并在这种情况下为它创建一个字段。考虑以下变化:
class Person(private val firstName: String, lastName: String) {
def fullName = firstName + " " + lastName
}
编译器可以知道它稍后可能需要lastName 的值,如果我们再次检查javap,我们将看到该类有两个字段(请注意,如果我们将fullName 定义为val 而不是 def,它只有一个字段)。
最后,请注意,如果我们使用 firstName object-private 而不是 class-private,它的工作方式与普通的无关键字构造函数参数完全相同:
class Person(private[this] val firstName: String, lastName: String)
即使使用 var 而不是 val,这也适用:
class Person(private[this] var firstName: String, lastName: String)
这两个类都没有字段。有关对象私有访问的更多详细信息,请参阅the language specification 的第 5.2 节。
【讨论】:
def fullName的例子中,private val和无关键字参数没有区别?
class Person(private[this] val firstName: String) 和 class Person(firstName: String) 生成字段 private[this] val firstName: String stackoverflow.com/a/62686327/5249621
作为补充,如果你的类是case类,所有的构造函数参数都会自动成为public字段。
如果private关键字存在,编译器会报错,对于没有val/var的参数,无论是否在任何defs中使用,都会为它们生成公共字段。
【讨论】: