안녕하세요. 궁금증연구소 입니다.
오늘 포스팅 주제는 "[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는 변수 값으로 람다식 내부에서 참조할수 없는 변수이다.
위 예시의 경우 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를 람다 식에 사용할 수 있습니다. 요약하면 변수에 값이 한 번만 할당되고 해당 값이 다시 수정되지 않는 경우 변수는 효과적으로 최종 변수가 될 수 있습니다. 최종 변수가 아닌 변수는 람다 식을 만든 후 변수 값이 잠재적으로 변경될 수 있으므로 람다 식에 사용할 수 없습니다.
[java] 와일드카드의 쓸모:: 읽을수 있으나, 쓸수 없다(vice-versa) (0) | 2023.04.10 |
---|---|
[Java] 람다와 익명내부클래스의 차이점은? (0) | 2023.04.10 |
[코드업 Java100제] 1023 : [기초-입출력] (0) | 2023.04.05 |
[Java] 삼항연산자로 조건 3개인 경우 처리하는 방법은? (0) | 2023.03.06 |
java 문자형 숫자를 숫자형(int)로 바꾸는 방법 (0) | 2022.11.26 |