2010-05-04 2 views
2

안녕하세요 저는 내부 클래스에 관한 SCJP 책을 통해이 문장을 발견했습니다.메쏘드의 로컬 변수에 접근하는 메쏘드의 로컬 변수에 접근하는 로컬 내부 클래스

있어서 로컬 클래스는

final 표시 및 설명에 규정 이유 범위 및 수명 로컬 클래스 객체 및 로컬 변수에 관한되는 로컬 변수를 참조 할 힙,하지만 나는 그것을 이해할 수 없습니다. 내가 여기에 아무것도 놓치고있다 final ??

답변

6

이유는 메서드 로컬 클래스 인스턴스가 만들어지면 해당 메서드가 참조하는 모든 메서드 로컬 변수가 실제로 컴파일러에 의해 복사됩니다. 그렇기 때문에 final 변수 만 액세스 할 수 있습니다. final 변수 또는 참조는 변경 불가능하므로 메서드 로컬 객체 내에서 해당 복사본과 동기화 상태를 유지합니다. 그렇다고해서 메소드 로컬 클래스를 생성 한 후에 원래의 값/참조를 변경하여 혼동을주는 행동과 미묘한 버그를 일으킬 수있었습니다.

JavaSpecialist newsletter no. 25에서 예 고려해

class Access1$1 implements Runnable { 
    Access1$1(Access1 access1) { 
    this$0 = access1; 
    } 
    public void run() { 
    System.out.println(3); 
    } 
    private final Access1 this$0; 
} 

i의 값이 마지막이기 때문에, 컴파일러 수 "인라인"

public class Access1 { 
    public void f() { 
    final int i = 3; 
    Runnable runnable = new Runnable() { 
    public void run() { 
     System.out.println(i); 
    } 
    }; 
    } 
} 

컴파일러는 이것으로 내부 클래스 변 그것은 내부 클래스로.

+0

뉴스 레터 링크에 대한 명확한 설명 및 문제를 보내 주셔서 감사합니다. 매우 도움이됩니다. – flash

2

메소드 - 로컬 클래스 (예 : 익명 클래스)에서 로컬 변수에 액세스하는 것은 위험한 일입니다. 그것은 컴파일러에 의해 허용되지만, 무슨 일이 일어나고 있는지 잘 이해할 필요가 있습니다.

내부 클래스가 인스턴스화 될 때 사용되는 로컬 변수에 대한 모든 참조가 복사되고 암시 적 생성자 매개 변수로 전달됩니다 (바이트 코드 확인). 실제로 컴파일러는 참조를 비 최종으로 만들 수는 있었지만 인스턴스가 생성 된 후 참조가 변경되면 어떤 일이 발생하는지 분명하지 않기 때문에 혼동 스러울 수 있습니다.

그러나 참조 최종본을 작성한다고해서 모든 문제가 해결되는 것은 아닙니다. 참조가 변경되지는 않지만 참조 뒤에있는 객체는 여전히 변경 가능할 수 있습니다. 내부 클래스에 의해 활성화 될 때까지 내부 클래스의 인스턴스 생성 사이에서 수행 된 객체의 모든 변형. 때로는 프로그래머의 의도가 아닙니다.

관련 문제