私有var构造函数参数和没有val / var的构造函数参数之间有什么区别?它们的范围/可见度是否相同?
前:
class Person(private var firstName:String, lastName:String)
答案 0 :(得分:27)
是的,有两个重要的区别。首先是简单的:没有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
,我们会看到该类有两个字段(请注意,如果我们定义了{ {1}} fullName
代替val
,它只有一个字段。
最后,请注意,如果我们将def
object-private 而不是 class-private ,那么它的工作方式与普通的无关键字构造函数参数完全相同:
firstName
即使使用class Person(private[this] val firstName: String, lastName: String)
代替var
:
val
这两个类都没有字段。有关对象 - 私有访问的更多详细信息,请参阅the language specification的第5.2节。
答案 1 :(得分:1)
作为补充,如果您的类是一个案例类,则所有构造函数参数都将自动为公共字段。
编译器会抱怨private关键字(如果存在),对于没有val / var的参数,无论是否在任何defs中使用它们,都会为它们生成公共字段。