[java] 자바 : Class.this

이와 같은 Java 프로그램이 있습니다.

public class LocalScreen {

   public void onMake() {
       aFuncCall(LocalScreen.this, oneString, twoString);
   }
}

무엇을 LocalScreen.this의미 aFuncCall합니까?



답변

LocalScreen.thisthis둘러싸는 클래스를 나타냅니다 .

이 예는이를 설명해야합니다.

public class LocalScreen {

    public void method() {

        new Runnable() {
            public void run() {
                // Prints "An anonymous Runnable"
                System.out.println(this.toString());

                // Prints "A LocalScreen object"
                System.out.println(LocalScreen.this.toString());

                // Won't compile! 'this' is a Runnable!
                onMake(this);

                // Compiles! Refers to enclosing object
                onMake(LocalScreen.this);
            }

            public String toString() {
                return "An anonymous Runnable!";
            }
        }.run();
    }

    public String toString() { return "A LocalScreen object";  }

    public void onMake(LocalScreen ls) { /* ... */ }

    public static void main(String[] args) {
        new LocalScreen().method();
    }
}

산출:

An anonymous Runnable!
A LocalScreen object

이 게시물은 여기 에 기사로 다시 작성되었습니다 .


답변

그것은 this외부 LocalScreen클래스 의 인스턴스를 의미합니다 .

this한정자없이 작성 하면 호출이 포함 된 내부 클래스 의 인스턴스가 반환됩니다 .


답변

컴파일러는 코드를 가져 와서 다음과 같이합니다.

public class LocalScreen
{
    public void method()
    {
        new LocalScreen$1(this).run;
    }

    public String toString()
    {
        return "A LocalScreen object";
    }

    public void onMake(LocalScreen ls) { /* ... */ }

    public static void main(String[] args)
    {
        new LocalScreen().method();
    }
}

class LocalScreen$1
     extends Runnable
{
    final LocalScreen $this;

    LocalScreen$1(LocalScreen $this)
    {
        this.$this = $this;
    }

    public void run()
    {
        // Prints "An anonymous Runnable"
        System.out.println(this.toString());

        // Prints "A LocalScreen object"
        System.out.println($this.toString());

        // Won't compile! 'this' is a Runnable!
        //onMake(this);

        // Compiles! Refers to enclosing object
        $this.onMake($this);
    }

    public String toString()
    {
        return "An anonymous Runnable!";
    }
}

보시다시피 컴파일러가 내부 클래스를 가져 오면이를 외부 클래스로 변환합니다 (이것은 내부 클래스를 이해하기 위해 VM을 변경할 필요가 없도록 오래 전에 내린 설계 결정이었습니다).

비 정적 내부 클래스가 만들어지면 외부 클래스의 메서드 / 액세스 변수를 호출 할 수 있도록 부모에 대한 참조가 필요합니다.

내부 클래스의 내부는 적절한 유형이 아닙니다. onMake 메서드를 호출하기위한 올바른 유형을 얻으려면 외부 클래스에 대한 액세스 권한을 얻어야합니다.


답변

Class.this외부 클래스의 인스턴스에 대한 액세스를 허용합니다. 다음 예를 참조하십시오.

public class A
{
  final String name;
  final B      b;
  A(String name) {
    this.name = name;
    this.b = new B(name + "-b");
  }

  class B
  {
    final String name;
    final C      c;
    B(String name) {
      this.name = name;
      this.c = new C(name + "-c");
    }

    class C
    {
      final String name;
      final D      d;
      C(String name) {
        this.name = name;
        this.d = new D(name + "-d");
      }

      class D
      {
        final String name;
        D(String name) {
          this.name = name;
        }

        void printMe()
        {
          System.out.println("D: " + D.this.name); // `this` of class D
          System.out.println("C: " + C.this.name); // `this` of class C
          System.out.println("B: " + B.this.name); // `this` of class B
          System.out.println("A: " + A.this.name); // `this` of class A
        }
      }
    }
  }
  static public void main(String ... args)
  {
    final A a = new A("a");
    a.b.c.d.printMe();
  }
}

그러면 얻을 것입니다.

D: a-b-c-d
C: a-b-c
B: a-b
A: a


답변

당신의 혼란이 뭔지 알아요 지금 막 문제가 생겼는데 구분할 수있는 특별한 장면이 있어야합니다.

class THIS {
  def andthen = {
    new THIS {
      println(THIS.this.## + ":inner-THIS.this.##")
      println(this.## + ":inner-this.##")
      new THIS {
        println(THIS.this.## + ":inner-inner-THIS.this.##")
        println(this.## + ":inner-this.##")
      }
    }
  }
  def getInfo = {
    println(THIS.this.## + ":THIS.this.##")
    println(this.## + ":this.##")
  }
}

당신의 사랑하는 볼 수 THIS.thisthis해시 코드에 의해이 작업 새로운에서을 (. ##)

스칼라 콘솔에서 테스트 :

scala> val x = new THIS
x: THIS = THIS@5ab9b447

scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1@181d7f28

scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##

THIS.this항상 val x에 의해 참조되는 외부 THIS 클래스를 가리 키지 만 this익명의 새 작업을 넘어서는 것입니다.


답변