나의 게시글들은 내가 겪었던 문제이거나 호기심에 파고들다 알게 된 내용들이다.
이번 포스팅은 호기심에 파고들다 알게 된 내용이며 나 뿐만이 아니라 모든 자바 개발자도 알면 좋을 것 같다.
먼저, 람다의 정확한 정의를 알고가보자.
람다란?
- 람다 표현식은 메서드로 전달할 수 있는 익명 함수를 단순화 한것이다.
- 람다 표현식에는 이름은 없지만, 파라미터 리스트, 바디, 반환 형식, 발생할 수 있는 예외 리스트는 가질 수 있다.
람다의 특징
- 익명
보통의 메서드와 달리 이름이 없으므로 익명이라 표현한다. 구현해야 할 코드에 대한 걱정거리가 줄어든다. - 함수
람다는 메서드처럼 특정 클래스에 종속되지 않으므로 함수라고 부른다. 하지만 메서드처럼 파라미터 리스트, 바디, 반환 형식, 가능한 예외 리스트를 포함한다. - 전달
람다 표현식을 메서드 인수로 전달하거나 변수로 저장할 수 있다. - 간결성
익명 클래스처럼 많은 자질구레한 코드를 구현할 필요가 없다.
람다의 사용
개발자는 정의가 아닌 코드로 보면 더 이해가 잘되기에(주관적으로 나는 그렇다) 기존 코드를 람다로 바꿔보겠다.
기존 코드
Comparator<HoyasArray> comparator = new Comparator<HoyasArray>() {
public int compare(HoyasArray a1, HoyasArray a2){
// 해당 compare는 오름차순으로 정렬한다.
return a1.getIntNum().compareTo(a2.getIntNum());
}
}
람다 코드
Comparator<HoyasArray> comparator =
(HoyasArray a1, HoyasArray a2) -> a1.getIntNum().compareTo(a2.getIntNum());
람다의 정의에 대해선 여기까지 알아보고 이제 진짜 본론으로 들어가겠다.
람다에서의 지역 변수 사용
모든 람다는 인수(파라미터 변수)를 자신의 바디 안에서만 사용했다. 하지만, 람다에서는 익명 함수가 하는 것처럼 자유 변수(파라미터로 넘겨진 변수가 아닌 외부에서 정의된 지역 또는 전역 변수)를 활용할 수 있다. 이와 같은 동작을 람다 캡처링이라고 부른다.
람다 캡처링
이름 그대로 람다에 지역 변수를 넘길때 그 순간을 캡처 해서 사용한다는 것이다.
만약 Integer a = 1; 이라 선언 되어 있다면, 람다에서는 a에 담긴 1을 가져오는것이다.
위의 말로는 이해가 자세히 되지 않을것이다. 예제를 보며 천천히 설명하겠다.
int num = 10;
Runnable r = () -> System.out.println(num);
놀랍게도(?) 정상적으로 컴파일 및 작동을 한다. 이유는 위에서와 같이 람다 캡처링이라는 동작을 통해 num에 담긴 10을 가져왔기 때문이다.
자 이제 생각해보자. 람다 캡처링. 그 순간을 캡처 하여 가져온다...
만약 이렇게 된다면 어떻게 될까?
int num = 10;
Runnable r = () -> System.out.println(num);
num = 20; // 변경
위와 다른점은 num의 값을 람다 선언 이후에 변경해주었다는 것이다. 이렇게 하면 정상적인 컴파일이 되지 않을것이다.
왜? 이런 제약이 있는거야?
메모리 관련해서 깊이 들어가보자. 일단 내부적으로 인스턴스 변수와 지역 변수는 저장되는 위치 부터가 다르다.
인스턴스 변수는 힙에 저장되지만 지역 변수는 스택에 위치한다.
람다가 지역 변수에 바로 접근할 수 있다는 가정을 세워보자.
람다는 Thread A 에서 실행 되고 지역변수는 Thread B 에서 할당하고 종료 되었다면, 변수 할당이 해제되었는데도 람다를 실행하는 Thread A 에서는 해당 변수에 접근하려 할 수 있다.
이게 실제 서버에서 일어나면?.. 상상만해도 정말 위험하다..
결론
람다는 자유 변수를 캡처 형식으로 가져온다. 즉, 처음 가져오기 전에 갖고 있던 상태를 가져오는 것이다.
따라서 자유 변수를 람다 내에 가져오려면 final로 선언할 때와 동일하게 사용되어야 한다.
다음 포스팅은 스프링에서의 HTTP 요청 및 응답 과정에 대해 써보려 한다.
'Java' 카테고리의 다른 글
[Java] 자바에서의 동기화는 왜 어렵고 까다로울까? (0) | 2022.06.16 |
---|