익명 클래스는 새로 *스콥을 만들지만, 람다는 람다를 감싸고 있는 범위와 같은 *스콥을 가진다.
스콥(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인 경우에만 변수를 참조할 수 있다.
- 익명 클래스는 새로 스콥을 만들지만, 람다는 람다를 감싸고 있는 스콥과 동일한 스콥을 가진다.
혹시 썸네일은 어떻게 만드시나요??