2017-12-27 9 views
3

저는 Java 8 스트림을 연구 중이므로 람다를 이해하는 것이 람다에 대한 최종 경고가 무시되는 이유입니다 예를 들어 (그리고 정적 인) 변수들. 나는 대부분의 페이지가 단지 "사실상 최종적인"이라는 정의에 관해서 이야기 할 것이므로, 온라인에 대한 어떤 언급도 찾을 수없는 것 같다.왜 "람다 식에 사용되는 변수가 최종 변수이거나 최종 변수 여야합니다"라는 경고가 인스턴스 변수에 대해 무시됩니다.

public class LambdaTest { 

    int instanceCounter = 0; 

    public void method() { 
     int localCounter = 0; 
     instanceCounter = 5; //Re-assign instance counter so it is no longer effectively final 

     Stream.of(1,2,3).forEach(elem -> instanceCounter++); //WHY DOES THE COMPILER NOT COMPLAIN HERE 
     Stream.of(1,2,3).forEach(elem -> localCounter++); //Does not compile because localCounter is not effectively final 
    } 
} 

답변

4

우리는 instanceCounter 실제로 this.instanceCounter, 당신이 잘, 효과적으로 최종있는 this을 캡처하는 것을 잊지하는 경향이있다. 에 관해서는이 필요합니다. 대답은 분명히 here

입니다.
4

왜 로컬 변수에 대한 컴파일 오류가 발생합니까?

실제로 최종 규칙은 전역 변수가 아닌 로컬 변수에만 적용되므로 전역 변수를 변경할 때 첫 번째 시나리오에 대한 컴파일 오류가 없습니다.

은 그래서 컴파일 에러가없는 최종 지역 변수 을 캡처로 볼 수있다 인스턴스 변수를 캡처하는 데 도움합니다.

왜 이러한 제한이 있습니까? 다음과 같이

이 책 자바-8 액션에서이 제한에 대한 올바른 설명을 가지고, 그것은 간다 :

를 지역 변수이 제한이 왜 자신을 질문 할 수있다. 첫째, 인스턴스와 로컬 변수가 백그라운드에서 어떻게 구현되는지에 주요 차이점이 있습니다. 인스턴스 변수 은 힙에 저장되는 반면 로컬 변수는 스택에 저장됩니다. 람다가 로컬 변수에 직접 액세스 할 수 있고 람다가 스레드에서 사용 된 인 경우 람다를 사용하는 스레드는 변수를 할당 한 스레드가 을 할당 해제 한 후에 변수 에 액세스하려고 시도 할 수 있습니다. 따라서 Java는 원래 변수에 액세스하지 않고 무료 로컬 변수 에 대한 액세스 권한을 액세스에 구현합니다.

로컬 변수가 에만 할당되면이 제한이 적용되므로 아무런 차이가 없습니다. 둘째,이 제한은 외부 변수를 변형시키는 전형적인 명령형 프로그래밍 패턴을 방해하기도합니다 ( ).