25

私有 var 构造函数参数和没有 val/var 的构造函数参数有什么区别?它们在范围/可见性方面是否相同?

前任:

class Person(private var firstName:String, lastName:String)
4

2 回答 2

29

是的,有两个重要的区别。首先是简单的:没有varorval关键字的构造函数参数不是可变变量——它们的值不能在类的主体中更改。

但是,即使我们将自己限制为val关键字,与无关键字参数之间仍然存在差异private val。考虑以下:

class Person(private val firstName: String, lastName: String)

如果我们用 来查看编译后的类javap -v Person,我们会发现它只有一个字段 for firstNamelastName只是一个构造函数参数,这意味着它可能在类初始化后被垃圾回收等。

编译器足够聪明,可以知道lastName初始化后何时需要 的值,并在这种情况下为它创建一个字段。考虑以下变化:

class Person(private val firstName: String, lastName: String) {
  def fullName = firstName + " " + lastName
}

编译器可以告诉它可能需要lastName稍后的值,如果我们javap再次检查,我们会看到该类有两个字段(注意,如果我们定义fullName为 aval而不是 a 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)

这两个类都没有字段。有关对象私有访问的更多详细信息,请参阅语言规范的第 5.2 节。

于 2013-09-04T21:40:33.700 回答
1

作为补充,如果你的类是case类,那么所有的构造函数参数都会自动成为public字段。

如果 private 关键字存在,编译器会报错,对于没有 val/var 的参数,无论是否在任何 defs 中使用,都会为它们生成公共字段。

于 2015-05-06T06:41:41.543 回答