web-dev-qa-db-ja.com

Java-'this'キーワードを使用する場合

Javaでthisキーワードを使用するためのベストプラクティスは何ですか?たとえば、次のクラスがあります。

class Foo {
    Bar bar;

    public Foo(Bar bar) {
         this.bar = bar;
    }
}

これで問題ありませんが、Javaは、コンストラクタ内のステートメントを

 bar = bar;

では、なぜthisキーワードを使用するのでしょうか? (状況によっては、それを使用することが完全に必要であり、このような状況を求めているだけです)。実際、私は読みやすさのためにキーワードを使用する傾向がありますが、一般的な慣習は何ですか?ショップ全体で使用すると、コードが少し面倒になります。たとえば、

boolean baz;
int someIndex = 5;
this.baz = this.bar.getSomeNumber() == this.someBarArray[this.someIndex].getSomeNumber();

明らかに不十分なコードですが、私の例を示しています。これらの場合、個人的な好みだけですか?

68
jackbot

しかし、Javaは、コンストラクタ内のステートメントを

  bar = bar;

偽!コンパイルしますが、あなたが思っていることはしません!

いつ使用するかについては、多くは個人的な好みです。パブリックメソッドでthisを使用するのは、それが不要な場合でも使用するのが好きです。なぜなら、それはインターフェイスが発生する場所であり、何が私のもので、何がそうでないかを主張するのが良いからです。

参照として、OracleのJava this.subjectについてのチュートリアル;-)を確認できます。

http://docs.Oracle.com/javase/tutorial/Java/javaOO/thiskey.html

75

フィールドと同じ名前のパラメーターがある場合に使用する必要があります。そうしないと、問題が発生します。コンパイルはされますが、必ずしも望んでいることを行うとは限りません。

それ以外の場合は、読みやすくするために必要な場合以外は使用しないでください。どこでも使用する場合、コードの20%が「this」という単語で構成されます。

13
Dónal Boyle

実は

baz = baz

この警告が発生します

変数bazへの代入は効果がありません

あなたが間違っていると思うのは、ローカルスコープがクラス属性をオーバーライドするためです[〜#〜] must [〜#〜]thisキーワードを明示的に使用してクラスに変数を割り当てます属性。

それ以外の場合、割り当てに使用される変数はパラメーターとして渡された変数のみであり、クラスの変数は無視されます。 thisが便利な理由は、読みやすさの事実ではなく、どのbazについて話しているのかを明示的に決定するという事実です。

私は言うだろう

thisを使用すると、あいまいさ(または、より重要なコンパイラ警告)が発生する場合はどこでも使用し、そうでない場合はそのままにしておきます。その目的は、デフォルトの仮定(最初にローカルをチェックし、次にクラス属性をチェックする)が十分でない場合の曖昧さを正確に解決することです。

11
Jack

thisキーワードは、何らかのメソッドが呼び出されるクラスのオブジェクトを参照します。
例えば:

_public class Xyz {  
    public Xyz(Abc ob)
    {
        ob.show();
    }
}

public class Abc {
    int a = 10;

    public Abc()
    {
        new Xyz(this);
    }

    public void show()
    {
        System.out.println("Value of a " + a);
    }

    public static void main(String s[])
    {
        new Abc();
    }
}
_

ここでAbc()では、Abcクラスのオブジェクトを必要とするXyz()を呼び出しています。したがって、新しいAbc()の代わりにthisを渡すことができます。ここに新しいAbc()を渡すと、それ自体が何度も呼び出されます。

また、これを使用して、クラスの変数とメソッドのローカル変数を区別します。例えば

_class Abc {
    int a;

    void setValue(int a)
    {
        this.a = a;
    }
}
_

ここで、_this.a_はクラスAbcの変数aを指します。したがって、新しいAbc().a;を使用するのと同じ効果があります。

したがって、thisは現在のクラスのオブジェクトを指していると言えます。

10
user291977

thisキーワードを明示的なコンストラクター呼び出しで使用するのが一般的です。 documentation から例を見ることができます。

public class Rectangle {
    private int x, y;
    private int width, height;

    public Rectangle() {
        this(0, 0, 1, 1);
    }
    public Rectangle(int width, int height) {
        this(0, 0, width, height);
    }
    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
    ...
}
7
public Foo(Bar bar) {
     this.bar = bar;
}

とは異なります

public Foo(Bar bar) {
     bar = bar;
}

2番目のケースでは、スコープ内のバーがパラメーターなので、自分自身に割り当てます。 this.barnullのままです。

6
David Soroko

それは個人的な好みです-スタイルを選択し、それに固執します。私は個人的にthisを使用していますが、他の人はそれが冗長だと考えています。

3
Andrew Hare

慣例に応じて、読みやすくするために使用できます。オブジェクト変数であることを強調しています。

また、変数と同じ名前のセッター引数が必要です(メソッドシグネチャの方が見やすい)。この場合、thisが必要です。

3
Konrad Garus

私は常にローカルクラスオブジェクトでthisキーワードを使用しようとします。

オブジェクトが静的オブジェクトかクラスオブジェクトかを視覚的に思い出させるために使用します。

これは、私とコンパイラがメソッドの引数とローカルクラスオブジェクトを区別するのに役立ちます。

public void setValue(int value){
  this.value = value;
}

クラスオブジェクトのカプセル化と区別するために、内部/ネスト/匿名クラスにそのようなローカルオブジェクトがあるかどうかを視覚的に思い出させるのに役立ちます。接頭辞thisがない場合、私の慣習はそれがカプセル化クラスのオブジェクトであることを思い出させるからです

public class Hello{
  public int value = 0;
  public boolean modal = false;

  public class Hellee{
    public int value = 1;
    public getValue(){
      if (modal)
        return 0;
      return this.value;
    }
  }
}
2
Blessed Geek
void set(int real)
{
    this.real = real;
}

ここでthisは、インスタンス変数がローカル変数と同じ場合に使用されるキーワードです。
別のthisの使用法は、コンストラクターのオーバーロードです。オーバーロードされたコンストラクターでコンストラクターを呼び出すことができます。

2
lagnajit

個人的な好みですが、あいまいさを解決するためだけに使用します。非常にまれなケースでは、割り当てられた変数がフィールドであることを明らかにすることを想定しています。すべてのフィールド参照で「this.field」を使用するプロジェクトがいくつかあります。この方法は視覚的に気が散るほど不快であると感じますが、そのようなコードをときどき見る準備をしておく必要があります。

私はひそかに、275個の「this」キーワードを含む500行のクラスを書く人々にとって特別な場所があると思いますが、このスタイルはいくつかのオープンソースプロジェクトで見られるので、それぞれに自分が推測します。

1
Decker

オブジェクトのクローン作成に使用します(コピーコンストラクターを介して自身の参照を渡します)。

Cloneableを継承するオブジェクトに役立ちます。

public Foo implements Cloneable {
  private String bar;

  public Foo(Foo who) {
    bar = who.bar;
  }

  public Object getClone() {
    return new Foo(this);  //Return new copy of self.
  }
}
0
Buhake Sindi