문제

끝의 코드는 컴파일 오류를 생성합니다.

NotApplicable.java:7: run() in  cannot be applied to (int)
                run(42);
                ^
1 error

문제는 왜 그런가? Javac이 내가 run ()에게 전화를 걸고 있다고 생각하는 이유는 무엇입니까 (int bar). FOO (int bar)를 올바르게라고합니다. 왜 내가 적용 할 수없는 것을 사용해야합니까? this.run (42);? 버그입니까?

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {
                foo(42);
                run(42);
                // uncomment below to fix
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}
도움이 되었습니까?

해결책

코드 샘플의 동작에 대한 설명은 this 당신이 현재 "가장"내부에있는 클래스로 정의됩니다. 이 경우, 당신은 익명의 내부 클래스 내부에서 서브 클래스를 실행할 수 있고 일치하는 방법이 없습니다. run(int). 검색을 넓히려면 어느 것을 지정합니다 this 당신은 언급하여 사용하고 싶습니다 NotApplicable.this.run(42).

JVM은 다음과 같이 평가합니다.

this -> 현재 인스턴스를 실행하고 있습니다 Runnable 방법으로 run()

NotApplicable.this -> 현재 인스턴스를 실행하고 있습니다 NotApplicable 방법으로 run(int)

컴파일러는 메소드 이름과 일치하는 첫 번째 메소드에 대해 둥지 트리를 찾습니다. -이 설명을 위해 Djclayworth에 감사합니다

익명의 내부 클래스는 외부 클래스의 서브 클래스가 아닙니다. 이 관계로 인해 내부 클래스와 외부 클래스는 정확히 동일한 서명을 가진 메소드를 가질 수 있어야하며 가장 안쪽 코드 블록은 실행하려는 메소드를 식별 할 수 있어야합니다.

public class Outer{

    public Outer() {
        new Runnable() {
            public void printit() {
                System.out.println( "Anonymous Inner" );
            }
            public void run() {
                printit(); // prints "Anonymous Inner"
                this.printit(); //prints "Anonymous Inner"

                // would not be possible to execute next line without this behavior
                Outer.this.printit(); //prints "Outer" 
            }
        };
    }

    public void printit() {
        System.out.println( "Outer" );
    }
}

다른 팁

중첩 클래스 사이에서 실행되는 메소드를 선택하는 규칙을 기억하는 한 상속 트리에서 메소드를 선택하는 규칙과 거의 동일합니다. 그것은 우리가 여기에 도착하는 것이 과부하가 아니라 숨어 있다는 것을 의미합니다. 이들 사이의 차이는 상속에서 방법을 이해하는 데 중요합니다.

Runnable이 서브 클래스로 선언 된 경우 run () 메소드는 부모의 run (int) 메소드를 숨 깁니다. 실행 요청 (...)은 Runnable에서 실행하려고 시도하지만 서명과 일치 할 수없는 경우 실패합니다. Foo는 아이에게 선언되지 않기 때문에 부모의 사람은 호출됩니다.

여기서도 같은 원칙이 일어나고 있습니다. "방법 숨기기"에 대한 참조를 찾아 보면 명확해야합니다.

이 때문입니다 run 당신이 입력 할 때 다시 고추되고 있습니다 new Runnable() {} 범위. 실행에 대한 모든 이전 바인딩은 접근 할 수 없게됩니다. 마치 당신이 이것을하는 것처럼 보입니다.

import java.util.*;

public class tmp
{
  private int x = 20;
  public static class Inner
  {
      private List x = new ArrayList();
      public void func()
      {
          System.out.println(x + 10);
      }
  }

  public static void main(String[] args)
  {
    (new Inner()).func();
  }
}

컴파일러는 x 범위 스택 위로 올라가면 첫 번째 참조를 찾을 때 중단되고 유형이 호환되지 않는 것을 알 수 있습니다.

노트: 마치 마치 마치 아닙니다 할 수 없었습니다 이렇게하십시오 ... 단지 자신의 정신을 보존하기 위해서는 안됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top