final 변수란 무엇인가?
자바에서 final 키워드로 선언된 변수는 한 번 초기화된 이후에는 더 이상 값을 변경할 수 없습니다. 즉, final 변수에는 단 한 번만 값을 할당할 수 있으며, 이미 값이 할당된 final 변수에 다시 값을 할당하려고 하면 컴파일 타임 오류가 발생합니다.
예제 코드
public class FinalExample {
final int j = 100;
public static void main(String args[]){
FinalExample obj = new FinalExample();
obj.j = 500;
System.out.println(obj.j);
}
}컴파일 타임 오류
위 코드처럼 final 변수에 두 번째 값을 할당하려고 시도하면 다음과 같은 컴파일 오류가 발생합니다.
FinalExample.java:6: error: cannot assign a value to final variable j obj.j = 500; ^ 1 error
final 키워드 없이 "한 번만 설정 가능" 기능 구현하기
final 키워드를 직접 사용하지 않으면서도 동일한 기능을 구현해야 하는 경우가 있습니다. 이때 활용할 수 있는 대표적인 방법은 다음과 같습니다.
변수를 private으로 선언하고, setter 메서드를 통해서만 값을 설정하도록 만듭니다. 그리고 setter 내부 로직에서 이미 값이 설정되어 있는 경우, 새로운 값을 덮어쓰지 않고 기존 값을 유지하거나, 아예 예외(RuntimeException)를 발생시켜 재할당 자체를 차단하는 방식입니다.
- 값 유지 방식: 두 번째 호출부터는 전달된 값을 무시하고 기존 값을 그대로 유지합니다.
- 예외 발생 방식: 두 번째 호출 시점에 런타임 예외를 던져 개발자에게 즉시 문제를 알립니다.
예제 코드
public class FinalExample {
private Integer num;
public void setNum(int num){
// 값이 null인 경우에만 새로 할당, 이후에는 기존 값 유지
this.num = this.num == null ? num : this.num;
}
private String data;
public void setData(String data) {
// 값이 이미 설정되어 있다면 demo() 메서드를 호출하여 예외 발생
this.data = this.data == null ? data : demo();
}
public String demo() {
String msg = "You cannot set value to the variable data for the second time";
throw new RuntimeException(msg);
}
public static void main(String args[]){
FinalExample obj = new FinalExample();
obj.setNum(200);
System.out.println(obj.num);
obj.setNum(500);
System.out.println(obj.num);
obj.setData("hello");
obj.setData("sample data");
}
}실행 결과
200 200 Exception in thread "main" java.lang.RuntimeException: You cannot set value to the variable data for the second time at SEPTEMBER.remaining.FinalExample.demo(FinalExample.java:15) at SEPTEMBER.remaining.FinalExample.setData(FinalExample.java:12) at SEPTEMBER.remaining.FinalExample.main(FinalExample.java:26)
정리
위 실행 결과에서 확인할 수 있듯이, setNum()은 두 번째 호출에서 전달된 값 500을 무시하고 처음 설정한 값 200을 그대로 유지합니다. 반면 setData()는 두 번째 호출 시점에 RuntimeException을 발생시켜 프로그램 실행을 중단시킵니다.
이처럼 private 필드와 조건부 setter 메서드를 조합하면, final 키워드 없이도 "한 번만 값을 설정할 수 있는 변수"를 구현할 수 있습니다. 다만 이 방식은 컴파일 타임 검증이 아니라 런타임에 제어한다는 점에서 진짜 final 변수와 차이가 있다는 점을 기억해야 합니다.