"Variable used in lambda expression should be final or effectively final"
개발중 마주하게된 메세지
서치로 찾아본 결과
람다 캡쳐링이라는 키워드를 알게 되었다.
알게된 내용을 정리한다.
람다 캡쳐링이란?
람다 캡처링이란 간단히 말해 외부 범위에서 선언된 변수를 람다 식 내부에서 사용하는 것을 의미한다.
이러한 변수는 자동으로 람다 표현식의 내부에 복사되거나(캡쳐링) 최종적으로 상수로 취급된다
예제로 이해하기
아래 코드일 경우 메모리 상황은 stack에 value =3 와 list 가 쌓이고 heep에 list의 값인 1,2,3,4가 쌓였다.
public static void main(String[] args) {
int value = 3;
List<Integer> list = Arrays.asList(1, 2, 3, 4);
}
forEach의 람다를 사용할 경우 stack을 복사하여 사용하게된다.
public static void main(String[] args) {
int value = 3;
List<Integer> list = Arrays.asList(1, 2, 3, 4);
list.forEach(x -> {
if (value == x) {
System.out.println("같다");
}
});
}
람다 캡쳐링이 일어나는 이유?
람다 캡쳐링 같은 동작은 자바 8부터 도입된 클로저(closure) 개념을 기반으로 하는데
보통 아래와 같은 이유로 캡쳐링이 일어난다.
일급 함수
람다 표현식은 일급 함수(first-class functions)로 취급되기 때문에 람다 표현식이 외부 변수를 캡쳐하여 저장하여 함수의 상태를 유지하게 되면, 함수를 일급 객체로 사용할 수 있다.
코드 유연성
외부 변수를 캡쳐함으로써 동적으로 변하는 상태를 람다 표현식 내에서 사용할 수 있다.
이는 함수형 프로그래밍의 원칙과 부합하며, 함수형 스타일의 코드 작성을 지원한다.
클로저란?
함수형 프로그래밍의 중요한 특징 중 하나인 클로저는 함수(람다)가 생성될 때의 환경(변수, 상태 등)을 기억하고,
함수가 나중에 다른 범위에서 호출될 때에도 처음 환경을 그대로 사용할 수 있게 한다.
'몰아 넣기' 카테고리의 다른 글
[Thymeleaf] th:each 사용해서 동적 html 생성하기 (feat.select 태그) (0) | 2023.09.03 |
---|---|
[Thymeleaf] replace, fragment 사용해서 레이아웃 나누기 (0) | 2023.09.03 |
[SptringSecurity] 스프링 시큐리티 WebSecurityConfigurerAdapter Deprecated 대처하기 (0) | 2023.05.01 |
[Java] 자바 record에 대해서 (0) | 2023.02.25 |
[자료구조] 우선순위 큐(priorityQueue) 알아보기 (with 자바) (0) | 2023.02.11 |