람다 표현식 - 변수 캡처 (Variable Capture)

준우·2022년 11월 16일
0

Java

목록 보기
24/30
post-thumbnail

익명 클래스는 새로 *스콥을 만들지만, 람다는 람다를 감싸고 있는 범위와 같은 *스콥을 가진다.

스콥(Scope)
변수를 선언했을 때, 그 변수가 접근이 가능한 범위.
예를 들어, for문 내에서 선언한 변수는 for문 밖에서 접근할 수 없다.

🤷🏻‍♀️ 무슨 소리일까?
예시 코드를 보면서 설명해보겠다.

예시 코드

package com.example.demo;

import java.util.function.Consumer;
import java.util.function.IntConsumer;

public class Foo {
	public static void main(String[] args) {
		Foo foo = new Foo();
		foo.run();

	}

	private void run() {
		int baseNumber = 10;

		// 로컬 클래스
		class LocalClass {
			int baseNumber = 11;

			void printBaseNumber() {
				System.out.printf("로컬 클래스: %d \n", baseNumber); // 11
			}

		}

		LocalClass localClass = new LocalClass();
		localClass.printBaseNumber();

		// 익명 클래스
		Consumer<Integer> integerConsumer = new Consumer<Integer>() {
			@Override
			public void accept(Integer baseNumber) {
				System.out.printf("익명 클래스: %d \n", baseNumber); // 12
			}
		};

		integerConsumer.accept(12);

		// 람다
		IntConsumer printInt = (i) -> {
			System.out.printf("람다: %d \n", i + baseNumber); // 10+3=13
		};

		printInt.accept(3);
	}
}

실행 결과

💡 정리

run() 메소드 안에 baseNumber라는 int형 변수를 선언해두었어도, 로컬 클래스나 익명 클래스에서는 각자 다른, 자신만의 스콥을 가지고 있어서 baseNumber라는 동일한 이름의 int형 변수를 또 선언하고,해당 범위 내에서 값을 재지정할 수 있다. 그런데 람다는, 람다가 위치해있는 스콥과 람다의 스콥이 동일하기 때문에 익명 클래스 구현체와 달리 "쉐도잉"하지 않는다는 특징이 있다. 사실상 람다가 참조하는 변수는 final인 것이다.

요약

  • 람다는 final이거나 effective final인 경우에만 변수를 참조할 수 있다.
  • 익명 클래스는 새로 스콥을 만들지만, 람다는 람다를 감싸고 있는 스콥과 동일한 스콥을 가진다.

References

1개의 댓글

comment-user-thumbnail
2022년 12월 27일

혹시 썸네일은 어떻게 만드시나요??

답글 달기