final 을 변수에 할당하면, 해당 변수는 값을 최초 한번만 초기화 할 수 있다. final 이 있다면, 메서드 호출 시점에 사용된 값이 변하지 않고 사용된다. 필드에서 사용할 경우 예시
public class ExClass {
final int vlaue; // final 사용
public ExClass(int value) {
this.value = value;
}
}
이와 같이 사용하면 생성자를 통해 처음 한번만 초기화 된다.
만약 static 을 final 앞에 붙이면 상수로 사용한다.
public class ExClass2 {
final int vlaue = 10;
static final int CONST_VALUE = 10;
}
}
그러면 인스턴스 생성만 해도 10으로 초기화된 변수가 생성된다.
static final 을 왜 쓰는 걸까?
final 로 필드 내 변수 초기화를 하게 되면, 인스턴스 생성 시 계속 같은 변수가 모든 인스턴스 메모리에 차지하게 된다. 하지만 static을 사용하면 메서드 영역에서 단 하나의 공간에서만 변수의 값이 저장되므로 훨씬 메모리적으로 효율적이다. 그림으로 보면 아래와 같다.

static final 즉, 상수로 초기화된 변수는 메서드 영역에서 하나로 관리 되지만 final 로 필드 변수에서 초기화를 진행하면 오른쪽 힙 영역 그림과 같이 계속 같은 값이 중복되어 메모리를 차지하게 된다.
참조값을 final 변수에 담을 수도 있다.
final Data data = new Data();
이렇게 사용하면 data 변수에 인스턴스의 참조값이 저장되고 참조값은 바뀔 수 없다. 하지만 참조값에 존재하는 변수의 값은 변경할 수 있다.
김영한의 자바 강의를 참고하였다.