궁금증 연구소

안녕하세요. 궁금증연구소 입니다.

오늘 포스팅 주제는 "[java] 람다식의 유효범위와 effective final" 입니다.

 

public class Test1 {

	public static void main(String[] args) {
		
		for(int i=0; i<100; i++) {
			new Thread(() -> System.out.println(i)).start();
		}
		
		int[] arr = {1,2,3,4,5,6,7};
		
		for( int arg : arr) {
			new Thread(() -> System.out.println(arg)).start();
		}
		
	}

}

자바에서 위와 같은 두개의 for문이 주어 졌을때,

 

1번째 for문은 에러가 발생한다. 왜일까?

 

오류

오류는

 

Local variable i defined in an enclosing scope must be final or effectively final

 

위와 같은데, 이는 결국 람다식의 유효 scope와 관련된 에러이다. 

람다식 내에서 자신을 감싸는 유효범위의 변수값을 캡쳐할 수 있는데, 

 

단, 이 값은

final 값이나, effective final 값만 캡쳐 가능하다.

 

effective final은 final을 붙이지 않았으나, 처음부터 끝까지 값이 변하지 않아 사실상 final값으로 받아들일수 있는 경우이다.

 

위 예제식의 i는 변수 값으로 람다식 내부에서 참조할수 없는 변수이다.

 

 

 

 

 

 

예제2

 

 

위 예시의 경우 int arg는 사실상의 최종변수 즉, effective final로 한번 값이 할당되면 변경되지 않으므로,

람다식 내부에서 사용이 가능하게 된다.

 

변수변경

 

위와같이 effective final을 for문 내부에서 한번이라도 값을 변경하게 되면, 같은 에러를 볼 수 있다.

 

 

<정리>

final int x = 10;
Runnable r = () -> System.out.println(x);
new Thread(r).start();

x는 최종 변수이므로 값을 변경할 수 없습니다. 따라서 아무런 오류 없이 람다 식에서 사용할 수 있습니다.

 

int y = 20;
y = y + 1; // y is reassigned a new value
final int z = y; // z is assigned the current value of y, which is effectively final
Runnable r = () -> System.out.println(z);
new Thread(r).start();

.

변수 y는 먼저 값 20으로 초기화된 다음 새 값으로 다시 할당됩니다. 그러나 변수 z에는 y의 현재 값이 할당되며 이는 다시 수정되지 않으므로 사실상 최종 값입니다. 따라서 오류 발생 없이 z를 람다 식에 사용할 수 있습니다. 요약하면 변수에 값이 한 번만 할당되고 해당 값이 다시 수정되지 않는 경우 변수는 효과적으로 최종 변수가 될 수 있습니다. 최종 변수가 아닌 변수는 람다 식을 만든 후 변수 값이 잠재적으로 변경될 수 있으므로 람다 식에 사용할 수 없습니다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band
loading