java_basic

람다와 익명클래스는 람다가 정의된 메서드의 지역변수의 값은 바꿀 수 없다

✨✨✨✨✨✨✨ 2023. 3. 11. 23:50
반응형
public class CloserTest {
    public static void main(String[] args) {
        int number = 10;

        Consumer<Integer> consumer = new Consumer<>() {
            @Override
            public void accept(Integer integer) {
                // Variable used in lambda expression should be final or effectively final
                number = 10;
                System.out.println(number);
            }
        };

        Consumer<Integer> consumer2 = integer -> {
            // Variable used in lambda expression should be final or effectively final
            number = 10;
            System.out.println(number);
        };
    }
}

위의 코드에서 number 변수는 main() 메소드의 지역 변수로 스택 메모리에 저장됩니다.

그리고 익명 클래스에서 number 변수를 사용하려고 하고 있습니다.

이 때, 익명 클래스는 consumer 변수에 저장되므로 힙 메모리에 저장됩니다.

 

자바에서는 익명 클래스에서 외부 변수를 참조할 경우, 해당 변수가 final 또는 effectively final 상태여야 합니다.

이는 스택 메모리에 있는 변수가 변경되면 그에 따라 힙 메모리에 있는 익명 클래스의 변수도 변경되어야 하는데, 이러한 상황을 방지하기 위함입니다.

따라서, 위의 코드에서 number 변수를 final 또는 effectively final로 선언하거나, 익명 클래스에서 number 변수를 변경하지 않도록 수정해야 합니다.

 

public class CloserTest {
    public static void main(String[] args) {
        int number = 10;

        Consumer<Integer> consumer = new Consumer<>() {
            @Override
            public void accept(Integer integer) {
                int number = 10; // 가능
                System.out.println(number);
            }
        };

        Consumer<Integer> consumer2 = integer -> {
            int number = 10; // 불가능
            System.out.println(number);
        };
    }
}

 

또한 Consumer의 경우 int number로 외부에 있는 변수명을 사용하는것이 가능하지만,

람다의 경우 외부와 같은 Scope로 인식하기에 불가능합니다.

반응형