2012-05-10 3 views
0

다음 코드에서 알 수 있듯이 ActionListener 익명 내부 클래스에서 JLabel에 액세스하고 있습니다. 이것은 오류없이 나를 제공하므로 어떻게 허용됩니까? 그러나 JLabel이 INSIDE 인 경우 메서드는 최종 한정자없이 허용되지 않습니까? 변수는 def 메서드 내 경우Java - 익명의 내부 클래스에서 최종 변수가 아닌 변수에 액세스하려면 어떻게해야합니까?

JLabel e = new JLabel(""); 
     public void myMethod() { 

      JButton b = new JButton("ok"); 
      b.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent arg0) { 
        e.setSize(200,200); 

       } 

      }); 

     } 
+1

가능한 복제본 [Java - 익명 내부 클래스의 변수 액세스] (http://stackoverflow.com/questions/10524635/java-accessing-variables-from-an-anonymous-inner-class) : 둘 다 이유를 묻습니다. 지역 변수가 아닌 최종 필드에 액세스해도 괜찮습니까? 또는 나는 무엇인가 놓쳤 느냐? 내가 그랬다면 - 분명히하십시오. – amit

답변

3

가, 다음은 지역 변수 - 그리고 당신이 그것으로 그 지역 변수의 수명을 그 메소드의 실행 후 존재 할 객체 인스턴스화되고, 메소드가 반환 될 때 파괴되는 메소드의 스택 프레임에있다. 이 작업을 수행하려면 을 모두 사용하십시오. 일부 컴파일러 마술이 필요합니다.이 작업은 현재 Java에서 구현이 절름발이 일지라도 closure이라고도합니다. 컴파일러는 실제로 ActionListener을 구현하고 로컬 변수의 값이 복사 될 인스턴스 변수를 갖는 클래스를 합성합니다.

스레드 안전성 문제로 인해 final 바스 위로 만 닫을 수있는 Java 관련 제한 사항입니다. 여기에있는 이야기는 Java 개발자의 직관에 따르면 로컬 var은 항상 스레드로부터 안전합니다. 메소드의 실행 중간에는 변경할 수 없으며 (메소드에서 명시 적으로 변경하지 않아도 됨) 거기에 데이터가 없다는 것 등이 있습니다. 비 최종 변수를 닫을 수있는 경우 현재 실행중인 메소드와 병렬로 실행될 수 있고 var를 변경하면 위반할 수 있습니다. 그것은 아주 직관력이없는 행동으로 이어질 것입니다.

은, 그러나, (다소 절름발이) 해결 방법은 :

public void myMethod() { 
    final JLabel[] e = {new JLabel("")}; 
    JButton b = new JButton("ok"); 
    b.addActionListener(new ActionListener() { 
     @Override public void actionPerformed(ActionEvent arg0) { 
     e[0].setSize(200,200); 
    }}); 
} 

e 이제 힙에 상주하며 방법의 StackFrame을 함께 파괴되지 않는 한 요소의 배열입니다. 직감을 적용하여 이 아닌은 thread-safe가 아니며 청취자는 e[0]의 값을 완전히 다른 것으로 쉽게 변경할 수 있으며 여기에 표시된 메소드는 명시 적 변이 코드가없는 변경을 관찰합니다. .

+0

* "스레드 안전성 문제로 인해 최종 vars에서만 닫을 수있는 Java 관련 제한 사항입니다."* - 사실 실제 최종 변수가 아닌 최종 변수 액세스에는 JVM에서 클로저를 지원해야합니다. 외부 메소드의 지역 변수는 다른 메소드 호출이 종료 된 후에도 살아 있어야합니다. 이 스레드를 트리거하기 위해 다중 스레드가 필요하지 않습니다 ... –

+0

하지만 ... ** ** ** 라이브로 남아 있습니다. 이 예제에서 우리는 액션이 ​​수행 될 때마다'e'를 역 참조합니다. 즉,'myMethod'가 과거에 리턴했던 방식입니다. –

관련 문제