パラメータが更新すべきフィールドを覆い隠してしまう
- オブジェクトの名前は"Ada"です。setName(String name)が引数"Bo"で実行されると、name = name; が行われます。
- 両方の未修飾ネームはパラメータを指すため、オブジェクトは依旧に"Ada"です。this.name = nameはパラメータの値をフィールドに割り当てます。
"このオブジェクト"
- インスタンスメソッド内において、
thisは メソッドが呼び出されたオブジェクト を指します。student.addScore(10)はthis= そのstudentで実行されます。 this.scoreは「私が操作しているオブジェクトのscore」を意味します。これにより、メソッドは自分のオブジェクトについて明示的に谈论できます。
フィールドとパラメータの区別
- 主な用途:同じ名前のパラメータとInstance Variable(インスタンス変数)を区別することです。
void setName(String name) { this.name = name; } this.nameはインスタンス変数であり、単なるnameはパラメータです。これは、3.8 のシャドウイング・バグに対する標準的な修正法です。
レシーバーオブジェクトへのアクセス
thisはメソッドに、それが呼び出された正確なオブジェクトへのハンドルを提供します。あなたが書かなくても、すべてのインスタンスメソッドには暗黙のthisが存在します。- scoreがシャドウされていないインスタンス変数を指す場合、
score += s;はthis.scoreを使用します。もしscoreという名のパラメータやローカル変数がそれをシャドウしている場合は、未修飾ネームは代わりにその変数を指します。シャドウを解消する場合のように、必要な時にのみthisを明示的に書きます。
this はレシーバーオブジェクトを指す
setName 内部では、this は呼び出された對象である ada です。
インスタンスメソッド内では、this は...を指します
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
this は現在のオブジェクトへのハンドルです。
In setName(String name) { this.name = name; } において、this.name は...
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
this.name はフィールドであり、単に name と書くとパラメータを指します。
this キーワードは静的メソッド内で使用できます。
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
静的メソッドには特定のオブジェクトがないため、this もありません。
setName(String name) 内で name = name; (thisなし)を書くとどうなりますか?
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
両方の名前はパラメータです;フィールドにアクセスするには this.name を使用します。
インスタンスメソッドすべてには、明示的に書かなくても暗黙の this があります。
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
インスタンスメソッドには現在の実行中のレシーバーがある。限定されない score は、パラメータやローカル変数がこのフィールドをシャドウイングしていない場合のみ this.score と解釈される。
静的メソッドにはthisがない
- 静的メソッドには**
thisがありません**。特定のオブジェクトに紐付いていないためです。したがって、静的メソッドはthisや未修飾のインスタンスフィールドを使用することはできませんが、アクセス権限が許容されている場合は、明示的な参照を通じてインスタンスフィールドを読み取ることは可能です。 - 静的メソッド内で
thisを使用しようとするとコンパイルエラーになります。thisが必要な場合は、メソッドは静的ではなくインスタンスメソッドである必要があります。
シャドーイングを回避するには this.field = param; を使用してください。this.name はインスタンス変数であり、単なる name はパラメータです。name = name; (this なし)と書くだけでは、パラメータ自身に代入されるだけになります。また、this は静的メソッド内には存在しません。静的メソッドには特定のオブジェクトがないため、そこで this を使うとコンパイルエラーになります。
Type the field value after the faulty setName("Bo") call on the described object.
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
The parameter assigns to itself; the field is unchanged until this.name is used on the left.
alias と a が同じ Student を参照する場合、alias.setName("Di") を実行すると、a を通して後で読み取った名前は変更される。
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
両方の参照は同じレシーバーオブジェクトを指し、そのフィールドが更新される。
オブジェクト b のコードが a.setName("Cy") を呼び出す。setName 内で this はどのオブジェクトを指すか?
難易度 1/5 · 100 コイン + 今日初回完了時に小ボーナス付与
他のオブジェクトのコードが呼び出しを開始したかどうかに関わらず、レシーバー a が this を提供している。
this を用いたシャドーイングバグの修正:
- インスタンス変数
private String name; void setName(String name) { this.name = name; }— 正しい!this.name(フィールド)にname(パラメータ)の値が入ります。
の推論を新しいケースへ適用せよ
- AdaとBoという名前を持つ別々に作成された学生aとbを追跡します。
a.setName("Cy")はaをCyに変更しますが、bは依旧にBoです。もしalias=aであれば、alias.setName("Di")はその同一の最初のオブジェクトを変更するため、aは現在はDi reads。 - レシーバーはインスタンスメソッドが作用するオブジェクトであり、必ずしもコードを呼び出したオブジェクトではありません。スタティックメソッドは明示的なオブジェクト参照上で動作できますが、暗黙的なthisはありません。
this は現在のオブジェクトを指し — インスタンスメソッドが呼び出されたオブジェクトです。その主要な用途はシャドーイングの解消です:this.name = name; はパラメータをインスタンス変数に代入します。すべてのインスタンスメソッドには暗黙の this が存在しますが、静的メソッドにはそれがないため、this は那里で使用できません。