25

private var コンストラクタ パラメータと val/var のないコンストラクタ パラメータの違いは何ですか? それらは範囲/可視性の点で同じですか?

元:

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

2 に答える 2

29

はい、2 つの重要な違いがあります。最初に簡単な例を挙げましょう。 varorvalキーワードのないコンストラクター パラメーターは変更可能な変数ではありません。それらの値は、クラスの本体で変更できません。

ただし、キーワードに限定したとしても、キーワードのないパラメーターとvalの間にはまだ違いがあります。private val次の点を考慮してください。

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

でコンパイルされたクラスを見るとjavap -v Person、フィールドが 1 つしかないことがわかりますfirstNamelastName単なるコンストラクタ パラメータです。つまり、クラスが初期化された後にガベージ コレクションされる可能性があります。

コンパイラは、初期化後に の値がいつ必要になるかを認識できるほどスマートでlastNameあり、その場合はそのフィールドを作成します。次のバリエーションを検討してください。

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

lastNameコンパイラは、後での値が必要になる可能性があることを認識できjavapます。もう一度確認すると、クラスに 2 つのフィールドがあることがわかります ( aではなく afullNameとして定義した場合、フィールドは 1 つしかないことに注意してください)。 .valdef

最後に、 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 を参照してください。

于 2013-09-04T21:40:33.700 に答える
1

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.

于 2015-05-06T06:41:41.543 に答える