this
が現在のオブジェクトを参照していることを私は知っています。しかし、いつそれを使用する必要があるのかわかりません。たとえば、一部のメソッドでthis.x
の代わりにx
を使用した場合、違いはありますか? x
は、対象となるメソッドにとってローカルな変数を参照する可能性がありますか私はこの方法でしか見られない変数を意味します。
this.method()
はどうですか?使用できますか?私はそれを使うべきです。 method()
を使用しただけでは、デフォルトでは現在のオブジェクトに適用されませんか。
this
キーワードは主に3つの状況で使用されます。最初で最も一般的なのは、変数参照を明確にするための設定メソッドです。もう1つは、現在のクラスインスタンスを別のオブジェクトのメソッドへの引数として渡す必要がある場合です。 3つ目は、コンストラクター内から代替コンストラクターを呼び出す方法としてです。
ケース1:変数参照を明確にするためにthis
を使用する。 Javaのセッターメソッドでは、通常、設定しようとしているプライベートメンバー変数と同じ名前の引数を渡します。それから引数x
をthis.x
に代入します。これにより、パラメータ "name"の値をインスタンス変数 "name"に代入していることが明らかになります。
public class Foo
{
private String name;
public void setName(String name) {
this.name = name;
}
}
ケース2:他のオブジェクトに渡される引数としてthis
を使用する。
public class Foo
{
public String useBarMethod() {
Bar theBar = new Bar();
return theBar.barMethod(this);
}
public String getName() {
return "Foo";
}
}
public class Bar
{
public void barMethod(Foo obj) {
obj.getName();
}
}
ケース3:代替コンストラクタを呼び出すためにthis
を使用する。コメントでは、 trinithis がthis
の別の一般的な使い方を正しく示していました。 1つのクラスに複数のコンストラクタがある場合は、コンストラクタの最初の行で指定した別のコンストラクタを呼び出すためにthis(arg0, arg1, ...)
を使用できます。
class Foo
{
public Foo() {
this("Some default value for bar");
//optional other lines
}
public Foo(String bar) {
// Do something with bar
}
}
私はthis
がインスタンス変数が参照されているという事実を強調するために使用されているのを見たことがありますが、それは私の意見ではまれなケースです。
this
の2番目の重要な使用法(多くの答えが言っているようにローカル変数で隠すことに加えて)は、入れ子になった非静的クラスから外部インスタンスにアクセスするときです。
public class Outer {
protected int a;
public class Inner {
protected int a;
public int foo(){
return Outer.this.a;
}
public Outer getOuter(){
return Outer.this;
}
}
}
同じ名前のローカル変数が重複している場合は、this
を使用するだけでよく、ほとんどの人はそれを使用するだけです。 (設定メソッドなど)
もちろん、this
を使うもう一つの良い理由は、それがインテリセンスをIDEにポップアップさせるということです:)
this.
修飾子を使用する唯一のneedは、現在のスコープ内の別の変数が同じ名前を共有していて、インスタンスメンバーを参照したい場合です(Williamが説明しているように)。それ以外は、x
とthis.x
の動作に違いはありません。
"this"はあるコンストラクタを他のコンストラクタから呼び出すときにも便利です。
public class MyClass {
public MyClass(String foo) {
this(foo, null);
}
public MyClass(String foo, String bar) {
...
}
}
this
はビルダーパターンで役立ちます。
public class User {
private String firstName;
private String surname;
public User(Builder builder){
firstName = builder.firstName;
surname = builder.surname;
}
public String getFirstName(){
return firstName;
}
public String getSurname(){
return surname;
}
public static class Builder {
private String firstName;
private String surname;
public Builder setFirstName(String firstName) {
this.firstName = firstName;
return this;
}
public Builder setSurname(String surname) {
this.surname = surname;
return this;
}
public User build(){
return new User(this);
}
}
public static void main(String[] args) {
User.Builder builder = new User.Builder();
User user = builder.setFirstName("John").setSurname("Doe").build();
}
}
変数名が重複していない限り、コードを読んでいるときは明確にするためです。
良い答えはたくさんありますが、this
を至るところに置くもう1つの非常に小さな理由があります。通常のテキストエディタ(例:メモ帳など)からソースコードを開こうとした場合、this
を使用すると読みやすくなります。
想像してみてください。
public class Hello {
private String foo;
// Some 10k lines of codes
private String getStringFromSomewhere() {
// ....
}
// More codes
public class World {
private String bar;
// Another 10k lines of codes
public void doSomething() {
// More codes
foo = "FOO";
// More codes
String s = getStringFromSomewhere();
// More codes
bar = s;
}
}
}
これは現代のIDEで読むのは非常に明らかですが、これは通常のテキストエディタで読むのは全くの悪夢になるでしょう。
エディタの "find"機能を使うまでは、foo
がどこにあるのかを探すのに苦労します。それから同じ理由でgetStringFromSomewhere()
を叫ぶでしょう。最後に、あなたがs
が何であるかを忘れた後、そのbar = s
があなたに最後の打撃を与えることになるでしょう。
これと比較してください。
public void doSomething() {
// More codes
Hello.this.foo = "FOO";
// More codes
String s = Hello.this.getStringFromSomewhere();
// More codes
this.bar = s;
}
foo
は外部クラスHello
で宣言された変数です。getStringFromSomewhere()
は外部クラスでも宣言されたメソッドです。bar
はWorld
クラスに属しており、s
はそのメソッドで宣言されているローカル変数であることがわかります。もちろん、何かをデザインするときはいつでも、ルールを作ります。あなたのAPIやプロジェクトを設計している間、あなたのルールが「誰かがメモ帳でこれらのすべてのソースコードを開くならば、彼または彼女が頭の中で彼/彼女自身を撃つべきである」を含むなら、あなたはしてはいけませんこれ。
@William Brendelの回答では、3つの異なるユースケースがありました。
ユースケース1:
this の公式Javaドキュメントページにも同じユースケースがあります。
インスタンスメソッドまたはコンストラクタ内では、これは現在のオブジェクト(そのメソッドまたはコンストラクタが呼び出されているオブジェクト)への参照です。これを使用して、インスタンスメソッドまたはコンストラクタ内から現在のオブジェクトの任意のメンバを参照できます。
2つの例があります。
Fieldとでこれを使用するコンストラクタとこれを使用する
ユースケース2:
この記事では引用していないその他の使用例:this
を使用して、マルチスレッドアプリケーションの現在のオブジェクトを同期させ、データとメソッドの重要なセクションを保護することができます。
synchronized(this){
// Do some thing.
}
ユースケース3:
Builder patternの実装は、変更されたオブジェクトを返すためのthis
の使用に依存します。
この記事を参照
GoogleはSunのサイトで、これについて少し説明したページを作成しました。
あなたは変数について正しいです。メソッド変数とクラスフィールドを区別するためにthis
を使うことができます。
private int x;
public void setX(int x) {
this.x=x;
}
しかし、私は本当にその慣習を嫌います。文字通り同一の名前を2つの異なる変数に与えることはバグのレシピです。私は以下の方針に沿って何かを好む。
private int x;
public void setX(int newX) {
x=newX;
}
同じ結果ですが、実際に代わりにx
を参照しようとしているときに誤ってx
を参照していたというバグの可能性はありません。
メソッドでそれを使うことに関しては、あなたは効果について正しいです。それがあってもなくても同じ結果が得られます。使えますか?もちろんです。あなたはそれを使うべきですか?あなたにもかかわらず、私が個人的には明瞭さを追加しないのは無意味な冗長性であると思うので(コードが静的import文でいっぱいに詰まっていない限り)、私はそれを自分で使うつもりはありません。
以下は、Javaで「this」キーワードを使用する方法です。
this
キーワードの使用this()
を使用して現在のクラスコンストラクタを呼び出すthis
キーワードの使用this
キーワードを使用https://docs.Oracle.com/javase/tutorial/Java/javaOO/thiskey.html
this
は、現在のオブジェクトへの参照です。これは、同じ名前を持つローカル変数と現在のクラス変数を区別するためにコンストラクタで使用されます。例えば。:
public class circle {
int x;
circle(int x){
this.x =x;
//class variable =local variable
}
}
this
は、あるコンストラクタを別のコンストラクタから呼び出すためにも使用できます。例えば。:
public class circle {
int x;
circle() {
this(1);
}
circle(int x) {
this.x = x;
}
}
2つの変数が同じ名前の1つのインスタンス変数と他のローカル変数があるとき、我々はこれを使います。現在の実行中のオブジェクトを参照して、名前間の競合を回避します。
いくつかの方法で "this.x"の代わりに "x"を使用した場合、違いはありますか?
通常はありません。しかしそれは時々違いを生む:
class A {
private int i;
public A(int i) {
this.i = i; // this.i can be used to disambiguate the i being referred to
}
}
単にmethod()を使用した場合、デフォルトでは現在のオブジェクトに適用されませんか。
はい。しかし必要に応じて、this.method()
は呼び出しがこのオブジェクトによって行われていることを明確にします。
this
は、結果のコードに影響を与えません。コンパイル時演算子であり、それを使用してもしなくても生成されるコードは同じになります。あなたがそれを使わなければならないとき、文脈によります。たとえば、クラス変数を隠すローカル変数があり、ローカル変数ではなくクラス変数を参照する場合は、前述のとおり使用する必要があります。
ローカルスコープ内のいくつかの変数がクラスに属しているものを隠さないとき、私はもちろん、「結果のコードは同じになるでしょう」ということで編集します。このように
class POJO {
protected int i;
public void modify() {
i = 9;
}
public void thisModify() {
this.i = 9;
}
}
両方のメソッドの結果のコードは同じになります。違いは、あるメソッドがローカル変数を同じ名前で宣言した場合です。
public void m() {
int i;
i = 9; // i refers to variable in method's scope
this.i = 9; // i refers to class variable
}
William Brendel の投稿と dbconfessions 質問に関して、case 2に関して。これが一例です。
public class Window {
private Window parent;
public Window (Window parent) {
this.parent = parent;
}
public void addSubWindow() {
Window child = new Window(this);
list.add(child);
}
public void printInfo() {
if (parent == null) {
System.out.println("root");
} else {
System.out.println("child");
}
}
}
これは、親子関係とオブジェクトとの関係を構築するときに使われるのを見たことがあります。ただし、簡潔にするために簡略化されています。