[Java8] 람다 표현식 : 스코프(Scope), 쉐도잉(Shadowing)
[Java8] 람다 표현식
람다 표현식에서의 스코프와 쉐도잉에 대해 알아보려 합니다.
https://joygotohome.tistory.com/113
[Java] 스코프 (Scope) / 쉐도잉 (Shadowing)
스코프 (Scope) 스코프 (Scope)스코프는 변수나 메서드가 유효하고 접근 가능한 범위를 의미합니다. 자바에서 스코프는 크게 두 가지로 나눌 수 있습니다: 블록 스코프와 클래스 스코
joygotohome.tistory.com
스코프와 쉐도잉의 기본 개념은 위 글을 참고해 주세요.
public class Foo {
public static void main(String[] args) {
Foo foo = new Foo();
foo.run();
}
private void run(){
int baseNumber = 10;
//로컬 class
class LocalClass {
int baseNumber = 11;
void printBaseNumber(){
System.out.println(baseNumber); //11
}
}
// 익명 class
Consumer<Integer> integerConsumer = new Consumer<Integer>() {
@Override
public void accept(Integer baseNumber) {
System.out.println(baseNumber); //parameter로 받아오는 값 출력됨
}
};
// 람다 = 익명함수
IntConsumer printInt = (i) -> {
System.out.println(i + baseNumber); //i+10
};
printInt.accept(10);
}
}
위와 같이 Foo 클래스가 있습니다.
코드의 구성만 본다면 위와 같은 형태인 것을 알 수 있습니다.
run 메소드에는 '로컬 Class / 익명 Class / 람다' 3가지 함수가 선언되어 있습니다.
코드를 함수로 구분한다면 위와 같은 형태가 되지만, 스코프와 쉐도잉 영역을 확인해보면 형태가 달라집니다.
baseNumber 스코프 = 람다 스코프
baseNumber 스코프 > 로컬 class 스코프
baseNumber 스코프 > 익명 class 스코프
스코프의 영역으로 본다면 위와 같은 형태가 됩니다.
그렇기 때문에 run()에 선언한 baseNumber라는 변수를 람다 안에서 사용할 때는 같은 baseNumber 입니다.
하지만 로컬class와 익명class에서는 baseNumber, baseNumber 를 재정의 하여 사용한다면 run안에 선언된 baseNumber와는 다른 baseNumber, baseNumber 가 되는 것이죠.
이것때문에 발생하는 이슈가 쉐도잉입니다.
run()에서 선언한 baseNumber가 로컬 class 안에서는 안에 선언한 baseNumber 값을 인식하여 11값을 출력하게 됩니다.
즉, 로컬class와 익명class는 각각의 스코프 영역을 가지고, 람다는 baseNumber와 같은 스코프 영역을 가지게 됩니다.
이것때문에 로컬class와 익명class에서는 쉐도잉 이슈가 발생하고, 람다에서는 쉐도잉 이슈가 발생하지 않습니다.
(final) int baseNumber = 10;
참고로 baseNumber는 final이 생략된 형태로 effecitve final 입니다.
변수를 선언 후 하위에서 변수값을 수정하지 않는다면 final이 생략된 effecitve final이 됩니다.
effective final은 람다에서 참조할 수 있습니다.
int baseNumber = 10;
baseNumber++;
하지만 위와같이 하위에서 변수의 값을 바꿔버린다면 더이상 effecitve final이 적용되지 않습니다.
그렇게되면 람다에서 baseNumber를 가져다 사용하게되면 오류가 발생됩니다.
'JAVA > JAVA8' 카테고리의 다른 글
[Java8] 인터페이스 default 메소드 / static 메소드 (0) | 2024.09.02 |
---|---|
[Java8] 메소드 레퍼런스 (0) | 2024.08.30 |
[Java8] JAVA가 제공하는 기본 함수형 인터페이스 정리 (0) | 2024.08.25 |
[Java8] 함수형 인터페이스, 람다식 변경 방법 (0) | 2024.08.25 |