プライベートvarコンストラクターパラメーターとval/varのないコンストラクターパラメーターの違いは何ですか?範囲/可視性の点で同じですか?
例:
class Person(private var firstName:String, lastName:String)
はい、2つの重要な違いがあります。まず簡単な方法です。var
またはval
キーワードのないコンストラクターパラメーターは可変変数ではありません。これらの値はクラスの本体で変更できません。
val
キーワードに制限したとしても、private val
パラメーターとキーワードなしパラメーターには違いがあります。次のことを考慮してください。
class Person(private val firstName: String, lastName: String)
コンパイルされたクラスをjavap -v Person
で見ると、firstName
のフィールドが1つしかないことがわかります。 lastName
は単なるコンストラクターパラメータです。つまり、クラスが初期化された後などにガベージコレクションされる可能性があります。
コンパイラは、初期化後にlastName
の値がいつ必要になるかを知るのに十分賢く、その場合はそのためのフィールドを作成します。次のバリエーションを検討してください。
class Person(private val firstName: String, lastName: String) {
def fullName = firstName + " " + lastName
}
コンパイラは、後でlastName
の値が必要になる可能性があることを認識でき、javap
をもう一度チェックすると、クラスに2つのフィールドがあることがわかります(fullName
をval
ではなくdef
として定義した場合は、フィールドは1つだけです)。
最後に、class-privateの代わりにfirstName
object-privateを作成すると、まったく古いキーワードとまったく同じように機能することに注意してください-コンストラクターパラメーターが少ない:
class Person(private[this] val firstName: String, lastName: String)
これは、var
の代わりにval
でも機能します。
class Person(private[this] var firstName: String, lastName: String)
これらのクラスは両方ともフィールドを持ちません。オブジェクトプライベートアクセスの詳細については、 言語仕様 のセクション5.2を参照してください。
補足として、クラスがケースクラスの場合、すべてのコンストラクターパラメーターは自動的にパブリックフィールドになります。
コンパイラは、privateキーワードが存在する場合は文句を言います。val/ varのないパラメータの場合、defで使用されているかどうかに関係なく、パブリックフィールドが生成されます。