자바를 공부하다 보면 static final을 붙여쓰는 경우가 있다.
대부분 절대불변의 성격을 가진 상수에 static final을 쓴다 정도로 알고있다.
그 이유를 알아보자.
public class FieldInit {
final int value = 10;
static final int CONST_VALUE = 10;
public static class FieldMain{
public static void main(String[] args) {
FieldInit fieldInit1 = new FieldInit();
FieldInit fieldInit2 = new FieldInit();
FieldInit fieldInit3 = new FieldInit();
System.out.println(fieldInit1.value); // 10
System.out.println(fieldInit2.value); // 10
System.out.println(fieldInit3.value); // 10
// 같은 10 이라는 숫자이지만 모두 다른 인스턴스로 힙영역의 메모리가 낭비됨.
//상수
System.out.println("상수");
System.out.println(FieldInit.CONST_VALUE); //10
}
}
}
위 코드를 보면 fieldInit1.value 의 값이 같은 10이다.
그렇지만 메모리 관점에서 보면 fieldInit1,fieldInit2,fieldInit3 각 객체 인스턴스의 value이기때문에 그 참조값이 다르다.
때문에 메모리의 힙영역 입장에서보면 같은 10이 3번 들어가있는것이다.

(인프런 김영한_자바 기본강의의 교육자료를 참고하였습니다)
이는 메모리의 낭비이기때문에 공통영역인 메소드 영역으로 value를 넘겨 메모리 낭비를 최소화한다.
final 은 변수의 값을 변경하지 못하게 막는다. 여기서 주의할 점이 있다.
정답은 [참조대상의 값만 변경이 가능하다] 이다. 아래의 예제를 보자.
public class Data {
public int value;
}
public class FinalRefMain {
public static void main(String[] args) {
final Data data = new Data();
final Data data2 = new Data(); //가능
data = new Data(); //final 변경 불가 컴파일 오류. data가 final 인것임.
//참조 대상의 값은 변경 가능
data.value = 10;
System.out.println(data.value);
data.value = 20;
System.out.println(data.value)
}
}
위 코드를 보면 final이 붙은건 정확히 data라는 참조형 변수이다. 때문에 data의 재선언이 불가능한것이다. 이는 참조형 변수에 들어가있는 참조값만 변경이 불가능하다는것이다.
쉽게말해 data 이제 다른 객체를 참조할 수 없다.
그렇지만 참조형변수 data가 참조하는 대상인 data.value는 변경이 가능하다.
때문에 final이 붙은 변수의 재선언은 주의가 필요하다.