자바 : Class.this


112

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

public class LocalScreen {

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

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

답변:


169

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

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


만약 당신이 다음과 같은 것을 가지고 있다면 : public class a { private class a { public void run() { System.out.println(a.this.toString()); } } 나는 그것이 같은 문제라고 생각합니다. a.this내에서이 run()받는 참조해야 바깥 athis. 내가 맞아? (이것은 축소 된 코드가 OSX 킨 미리보기 응용 프로그램의에 어떻게 .jar파일, 난 그냥 내가 찾고 있어요 이해하기 위해 노력하고있어.)
매트 맥

Java에서 내부 클래스는 포함하는 클래스 (JLS 8.1)와 동일한 이름을 가질 수 없으므로 a.this예제에서는 정의되지 않습니다. 이 제약 조건이 바이트 코드에 대해 참인지 모르겠습니다. 아마.
aioobe 2015-04-29

56

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

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


4
아직도 이해가 안 돼요. "this"와 비교하여 "LocalScreen.this"로 코딩 할 때의 차이점은 무엇입니까? 두 가지를 모두 테스트했고 컴파일러는 "LocalScreen.this"만 허용했습니다. aFuncCall의 첫 번째 매개 변수는 "Somethig"의 상위 클래스 인 aParent 클래스를 예상합니다.
Johnny Jazz

1
나도 이것에 대해 궁금합니다. 이것이 의미하는 바에 대해 자세히 설명해 주시겠습니까? 위 코드에 정의 된 내부 클래스가 없습니다. 모든 Java 함수에는 자신이 구성원 인 클래스와 별개로 연관된 익명 클래스가 있습니까?
poundifdef 2011

4
@rascher : 사용중인 내부 클래스가 있습니다. OP는 코드 스 니펫에 포함하지 않았습니다. 이 구문은 비 정적 내부 클래스에서만 지원됩니다.
SLaks 2011

공식 Java 문서에 대한 링크를 제공 해주셔서 감사합니다.
Krzysztof Tomaszewski

14

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

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 메서드를 호출하기위한 올바른 유형을 얻으려면 외부 클래스에 대한 액세스 권한을 얻어야합니다.


하지 말아야 new LocalScreen$1().run;new LocalScreen$1(this).run;?
Diskutant 2015-04-23

이것은 질문에 대한 과소 평가 된 답변입니다. 흥미로운 것들.
Pinkerton

12

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는 외부 클래스의 인스턴스에 대한 액세스를 허용합니다"이며 "Class.this는 외부 클래스의 this에 대한 액세스를 허용합니다"와 같은 것이 아닙니다. 클래스는 "이", 인스턴스 만이 ... 자신을 참조하기 위해이없는
Żabojad

-2

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

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익명의 새 작업을 넘어서는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.