본문 바로가기

JAVA

[JAVA8] Lambda(람다)에서 지역변수 사용하기

728x90
반응형

람다 표현식에서는 익명 함수가 하는 것처럼 자유 변수(파라미터로 넘겨진 변수가 아닌 외부에서 정의된 변수)를 사용할 수 있다.
이와 같은 동작을 람다 캡처링이라고 부른다.

람다에서는 인스턴스 변수와 정적 변수는 제약없이 캡처하여 사용할 수 있다. 즉 자신의 바디 영역에서 언제든지 사용할 수 있다는 의미이다.
하지만 지역 변수는 제약 사항이 있다.
final로 선언되어 있거나 실질적으로 final로 선언된 변수와 똑같이 사용되어야 한다.
즉 한번 할당한 지역 변수를 두번 할당하지 않는 지역변수만 람다에서 사용가능하다는 뜻이다.

아래 내용은 가능함.
int message = "hi";
Runnable r = () -> System.out.println(message);

아래 내용은 가능하지 않음.
int message = "hi";
Runnable r = () -> System.out.println(message);
message = "bye";

그렇다면 지역변수에만 이러한 제약이 있는 이유는 무엇일까?

그 이유는 인스턴스 변수는 힙에 저장되지만 지역 변수는 스택에 위치하기 때문이다.
람다가 실행되는 스레드에서 지역 변수를 참조할 때는 지역 변수의 복사본(읽기 전용)을 생성하고 참조하게 된다. 람다가 직접 지역 변수가 위치한 스택에 접근하게 되면 지역 변수가 할당한 스레드가 사라져 변수 할 당이 해제되었는데도 람다를 실행하는 스레드가 해당 변수를 접근하고자 하는 경우가 발생하게 되기 때문이다.
이와 같이 복사본(읽기 전용)을 사용하기 때문에 해당 변수의 값은 변경되어서는 안된다는 제약이 발생하게 된 것이다.

람다는 클로저를 지원 하는가?
자바8의 람다와 익명 클래스는 클로저와 비슷한 동작을 수행한다.
람다와 익명 클래스 모두 메서드의 인수로 전달될 수 있으며 자신의 외부 영역의 변수에 접근할 수 있다. 하지만 람다와 익명 클래스는 람다가 정의된 메서드의 지역 변수의 값은 바꿀 수 없다.

 

*참고 : Java 8 in Action (한빛 미디어) 

728x90
반응형