"꾸준하고 완벽한 한 걸음"

Programming Language/Java

[Java] effectively final

kimyoungrok 2025. 1. 6. 17:23
728x90

Java를 사용하다 보면 effectively final라는 개념을 접하게 됩니다. 특히 람다 표현식이나 익명 클래스와 같은 구문을 작성할 때, 이 용어가 중요한 역할을 합니다.

이번 글에서는 effectively final에 대해 알아보도록 하겠습니다.


1. effectively final이란?

effectively final은 Java에서 한 번 초기화된 후로 값이 변경되지 않는 변수를 의미합니다.
쉽게 말해, final 키워드가 없어도 사실상 final처럼 동작하는 변수입니다.

int number = 10; // 초기화
Runnable task = () -> System.out.println(number); // 람다에서 number 사용 가능

위 코드에서 number는 한 번 초기화된 이후 변경되지 않았기 때문에 effectively final로 간주됩니다. 따라서 람다 표현식에서 안전하게 사용할 수 있습니다.

int number = 10;
number = 20; // 값이 변경됨
Runnable task = () -> System.out.println(number); // 컴파일 에러 발생

여기서 number는 값을 변경했기 때문에 effectively final이 아니며, 이를 람다 표현식에서 사용하면 컴파일 에러가 발생합니다.


2. 왜 effectively final이 중요한가?

effectively final은 주로 람다 표현식익명 클래스에서 사용됩니다.
람다 표현식이나 익명 클래스 내부에서 사용하는 외부의 지역 변수는 반드시 final 또는 effectively final이어야 합니다. 이는 다음 두 가지 이유 때문입니다

Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.
Any local variable used but not declared in a lambda body must be definitely assigned (§16 (Definite Assignment)) before the lambda body, or a compile-time error occurs.

https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4

 

Chapter 4. Types, Values, and Variables

class Point { static int npoints; int x, y; Point root; } class Test { public static void main(String[] args) { System.out.println("npoints=" + Point.npoints); Point p = new Point(); System.out.println("p.x=" + p.x + ", p.y=" + p.y); System.out.println("p.

docs.oracle.com

(1) 불변성 보장

effectively final은 변수가 변경되지 않는다는 보장을 제공합니다. 이는 멀티스레드 환경에서 데이터 일관성을 유지하고, 예상치 못한 동작을 방지하는 데 도움이 됩니다.

(2) Java 내부 구현

Java에서는 람다 표현식이나 익명 클래스가 외부 변수에 접근할 때 해당 변수의 복사본을 사용합니다. 만약 외부 변수의 값이 변경된다면, 람다 내부의 값과 외부 값이 서로 달라질 수 있습니다. 이러한 혼란을 방지하기 위해 effectively final 제약이 적용됩니다.

 


3. final과 effectively final의 차이점

특징 final effectively final
선언 시 키워드 필요 여부 final 키워드가 반드시 필요 키워드 없이도 조건 만족 시 적용
값 변경 가능 여부 초기화 이후 값 변경 불가 초기화 이후 값 변경하지 않은 경우 해당
컴파일러의 역할 키워드로 값 변경 불가를 명시적으로 확인 코드 흐름 분석으로 값 변경 여부 판단

4. 결론

effectively final은 Java에서 한 번 초기화된 변수의 불변성을 보장하는 중요한 개념입니다. 특히 람다 표현식과 익명 클래스에서 외부 변수를 사용할 때 필수적으로 요구됩니다. 이를 이해하고 올바르게 활용하면, 더 안전하고 예측 가능한 코드를 작성할 수 있습니다.

여러분의 코드에서 effectively final을 활용해 보세요! 😄

728x90