Java

[Java] 객체지향 - final 2

parangofsky 2026. 1. 9. 18:00

- 그렇다면, 컴파일 과정에서 final이 붙으면 차이점이 있을까?

 

1. 컴파일 타임 상수

final 변수 중에서도 선언과 동시에 리터럴 값으로 초기화된 static final 변수(예: static final int MAX = 10;)는 컴파일 타임 상수로 취급.

  • 인라인화(Inlining): 컴파일러는 코드에서 이 변수를 참조하는 부분을 실제 값으로 치환.
  • 실행 속도 향상: 런타임에 변수를 찾기 위해 메모리 주소를 참조할 필요 없이, 즉시 값을 사용하므로 성능이 미세하게 향상된다.
Java
 
// 컴파일 전
static final int AGE = 20;
int userAge = AGE;

// 컴파일 후 (바이트코드 수준)
int userAge = 20; // AGE 변수를 거치지 않고 직접 20이 주입됨

 

2. 메서드 인라인화 (Method Inlining)

final 메서드는 자식 클래스에서 재정의(Overriding)될 수 없음이 보장. 이 점은 JVM의 JIT(Just-In-Time) 컴파일러에게 아주 중요한 힌트.

  • 가상 메서드 호출(Virtual Method Call) 제거: 일반적인 메서드는 실행 시점에 어떤 객체의 메서드를 호출할지 결정하는 과정(다형성)이 필요.
  • 최적화: final 메서드는 호출 대상이 명확하므로, JIT 컴파일러가 메서드 본문의 내용을 호출부로 직접 복사해 넣는 인라인화를 수행하여 함수 호출 오버헤드를 줄인다.

3. 안정성과 재배치 방지 (Memory Visibility)

멀티스레드 환경에서 final은 컴파일러와 CPU의 재배치(Reordering) 방지 역할을 한다.

  • 안전한 초기화: 일반 변수는 생성자 안에서 값이 할당되더라도, 컴파일러 최적화에 의해 순서가 바뀌어 다른 스레드가 초기화되지 않은 값을 읽을 위험이 존재.
  • Garnered Visibility: final 변수는 객체가 완전히 생성되기 전에 값이 할당됨을 보장합니다. 따라서 생성자가 끝난 후 객체를 참조하는 다른 스레드는 항상 정확히 초기화된 final 값을 보게 된다.

'Java' 카테고리의 다른 글

[Java] 리플렉션(Reflection)  (0) 2026.01.13
[Java] 인터페이스와 추상클래스  (0) 2026.01.10
[Java] 객체지향  (0) 2026.01.08
[Java] JVM 2  (0) 2026.01.07
[Java] JVM에 대하여  (0) 2026.01.05