В чем разница между частным параметром конструктора var и параметром конструктора без val/var? Являются ли они одинаковыми с точки зрения охвата/видимости?
Пример:
class Person(private var firstName:String, lastName:String)
В чем разница между частным параметром конструктора var и параметром конструктора без val/var? Являются ли они одинаковыми с точки зрения охвата/видимости?
Пример:
class Person(private var firstName:String, lastName:String)
Да, есть два важных отличия. Сначала для простого: параметры конструктора без ключевых слов var
или val
не являются изменяемыми переменными - их значения не могут быть изменены в теле класса.
Даже если мы ограничимся ключевым словом val
, тем не менее, существует разница между параметрами private val
и keyword-less. Рассмотрим следующее:
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)
Оба этих класса не будут иметь полей. Дополнительную информацию об объектно-частном доступе см. В разделе 5.2 спецификации языка.
в качестве дополнения, если ваш класс является классом case, все параметры конструктора будут автоматически публичными.
Компилятор будет жаловаться на ключевое слово private, если оно существует, и для параметров без val/var, независимо от того, используются они или нет в каких-либо defs, для них будут созданы публичные поля.