private var コンストラクタ パラメータと val/var のないコンストラクタ パラメータの違いは何ですか? それらは範囲/可視性の点で同じですか?
元:
class Person(private var firstName:String, lastName:String)
private var コンストラクタ パラメータと val/var のないコンストラクタ パラメータの違いは何ですか? それらは範囲/可視性の点で同じですか?
元:
class Person(private var firstName:String, lastName:String)
はい、2 つの重要な違いがあります。最初に簡単な例を挙げましょう。 var
orval
キーワードのないコンストラクター パラメーターは変更可能な変数ではありません。それらの値は、クラスの本体で変更できません。
ただし、キーワードに限定したとしても、キーワードのないパラメーターとval
の間にはまだ違いがあります。private val
次の点を考慮してください。
class Person(private val firstName: String, lastName: String)
でコンパイルされたクラスを見るとjavap -v Person
、フィールドが 1 つしかないことがわかりますfirstName
。lastName
単なるコンストラクタ パラメータです。つまり、クラスが初期化された後にガベージ コレクションされる可能性があります。
コンパイラは、初期化後に の値がいつ必要になるかを認識できるほどスマートでlastName
あり、その場合はそのフィールドを作成します。次のバリエーションを検討してください。
class Person(private val firstName: String, lastName: String) {
def fullName = firstName + " " + lastName
}
lastName
コンパイラは、後での値が必要になる可能性があることを認識できjavap
ます。もう一度確認すると、クラスに 2 つのフィールドがあることがわかります ( aではなく afullName
として定義した場合、フィールドは 1 つしかないことに注意してください)。 .val
def
最後に、 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)
これらのクラスには両方ともフィールドがありません。object-private アクセスの詳細については、言語仕様のセクション 5.2 を参照してください。
as a supplement, if your class is a case class, all of the constructor parameters will be automatically public fields.
The compiler will complain about the private keyword if it exists, and for the parameters without val/var, no matter they are used or not in any defs, there will be public fields generated for them.