static class LambdaTest {
public static int MAX_NUM = 10000;
public int value = 3;
public void doTest(){
int regionValue = 1000;
LambdaTest lambdaTest1 = new LambdaTest();
LambdaTest lambdaTest2 = new LambdaTest();
Runnable r = () -> {
System.out.println(regionValue); // 에러 발생 지점2
lambdaTest1.value = 4; // 에러 발생 지점1
LambdaTest.MAX_NUM = 90;
System.out.println("lambdaTest.MAX_NUM = " + LambdaTest.MAX_NUM);
//lambdaTest1 = lambdaTest2; // 시도 시 지점2 에러 발생
};
r.run();
// regionValue = 20; // 시도시 지점1 에러 발생
System.out.println(lambdaTest1.value);
}
}
public static void main(String[] args) {
LambdaTest lambdaTest = new LambdaTest();
lambdaTest.doTest();
}
람다에서 접근 가능한 외부 변수
람다 캡처링
local variables referenced from a lambda expression must be final or effectively final
람다 표현식에 사용되는 변수는 final 또는 유사 final이어야 합니다
→ 값이 단 한번만 할당되는 지역변수만 캡처 가능하다는 의미람다캡처링 제약사항 이유
람다 실행을 위해 람다는 새로운 스택을 생성
실행되고 있던 메서드의 스택 데이터들을 람다의 스택으로 복사
이로 인해 람다 캡처링시 지역변수로 final 또는 유사 final 만 사용 가능하다는 제약사항이 존재하게 됨
*** effectively final : 유사final
반면 static 변수와 인스턴스 변수는 사용이 가능한데
Function<String, Integer> f = (String s) -> Integer.parseInt(s);
Function<String, Integer> f = Integer::parseInt;
// 클래스명::메서드명
BiFunction<String, String, Boolean> f1 = (s1, s2) -> s1.equals(s2);
BiFunction<String, String, Boolean> f2 = String::equals;
// 참조변수명::메서드명
String str = new String();
Function<String, Boolean> f3 = (x) -> str.equals(x);
Function<String, Boolean> f4 = str::equals;
Supplier<LambdaTest> s1 = () -> new LambdaTest();
Supplier<LambdaTest> s2 = LambdaTest::new;