수업에서 “this”를 언제 사용해야합니까? 대한 로컬 변수를 참조 할

나는 그것이 this현재 객체 를 참조 한다는 것을 알고 있습니다. 하지만 언제 사용해야하는지 모르겠습니다. 예를 들어, 일부 방법 x대신에 사용하면 차이가 this.x있습니까? 수 있음 x고려 방법에 대한 로컬 변수를 참조 할 것인가? 나는이 방법에서만 볼 수있는 변수를 의미합니다.

무엇에 대해 this.method()? 사용할 수 있습니까? 사용해야합니까? 방금을 사용 method()하면 기본적으로 현재 객체에 적용되지 않습니까?



답변

this키워드는 주로 세 가지 상황에서 사용됩니다. 첫 번째이자 가장 일반적인 것은 setter 메소드에서 변수 참조를 명확하게하는 것입니다. 두 번째는 현재 클래스 인스턴스를 다른 객체의 메서드에 대한 인수로 전달해야 할 때입니다. 세 번째는 생성자 내에서 대체 생성자를 호출하는 방법입니다.

사례 1 :this 변수 참조를 명확하게하기 위해 사용 . Java setter 메소드에서는 일반적으로 설정하려는 개인 멤버 변수와 동일한 이름의 인수를 전달합니다. 그런 다음 인수 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. 단일 클래스에 대해 여러 생성자가있는 경우 생성자 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이미 많은 대답이 말한 것처럼 로컬 변수로 숨기는 것 외에 중첩 된 비 정적 클래스에서 외부 인스턴스에 액세스 할 때입니다.

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.다른 현재 범위의 주 내에서 변수와 동일한 이름과 (윌리엄 설명 같은) 인스턴스 멤버를 참조 할 때 규정이다. 그 외에도 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어디에나 두어야 할 또 다른 사소한 이유가 있습니다. 일반 텍스트 편집기 (예 : 메모장 등)에서 소스 코드를 열려고하면 사용 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에서 읽는 것이 분명하지만 일반 텍스트 편집기로 읽는 것은 악몽이 될 것입니다.

foo에디터의 “find”기능을 사용하기 전까지는 어디에 있는지 알아 내기 힘들 것입니다. 그런 다음 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;
}
  1. 당신 foo은 외부 클래스에서 선언 된 변수 라는 것을 알고 Hello있습니다.
  2. getStringFromSomewhere()외부 클래스에서도 선언 된 메소드 라는 것을 알고 있습니다.
  3. 클래스에 bar속하고 해당 메소드에 선언 된 로컬 변수 라는 것을 알고 있습니다.Worlds

물론 무언가를 디자인 할 때마다 규칙을 만듭니다. 따라서 API 또는 프로젝트를 디자인 할 때 규칙에 “누군가이 소스 코드를 모두 메모장으로 열면 머리에 직접 촬영해야합니다”라는 규칙이 포함되어 있으면 를 수행하지 않는 것이 좋습니다.