평소 상수를 선언할 때 아래와 같은 형태로 코드를 작성한다.
관례적으로 이 방법을 사용한다는 것은 알고 있으나, 정확한 이유를 설명할 수 없다고 느껴 정리해보게 되었다.
public class Score {
private static final int MIN_score = 0;
private static final int MAX_score = 100;
}
final을 사용하면 해당 entity는 한 번 할당될 수 있다.
더 구체적으로 살펴보면 final 사용 용도에 따라 가지는 의미는 아래와 같다.
static은 해당 데이터의 메모리 할당을 컴파일 시간에 할 것임을 의미한다.
동적 데이터와 달리, static 데이터는 프로그램 실행 직후부터 끝날 때까지 메모리 수명이 유지된다.
그래서 왜 상수를 선언할 때 관례적으로 static final을 사용할까?
만약 상수를 static으로 선언하지 않은 경우, 클래스의 모든 인스턴스에 해당 상수에 대한 메모리를 할당한다.
상수를 선언하는 것은 변하지 않고 계속 일관된 값을 사용하기 위함이다.
(데이터와 그 의미, 용도를 고정)
상수는 모든 클래스 인스턴스에서 똑같이 써야할 값이고, 처음부터 끝까지 바뀌지 않아야 할 값이다.
위 사항들을 고려했을 때 static final로 상수를 선언하면 인스턴스가 만들어질 때마다 새로운 메모리에 초기화하지 않고, 하나의 메모리 공간만을 사용할 수 있다. 이렇게 되면 인스턴스 생성마다 매번 같은 메모리를 잡지 않아 효율적이다.
따라서 모든 곳에서 같은 값(하나의 값)으로 상수를 사용하는 경우에는 static으로 선언해야 한다. 만약 상수가 각 개체에 대해 다른 값을 가질 수 있는 경우 static으로 선언하면 안 된다.
모든 곳에서 하나의 값을 일관되게 사용하기 위해 상수를 선언할 때는 static final로 선언하는 것이 관례이다.
static final로 상수를 선언하면 인스턴스가 만들어질 때마다 새로운 메모리에 초기화하지 않고, 하나의 메모리 공간만을 사용할 수 있어 효율적이다.
만약 상수가 각 개체에 대해 다른 값을 가질 수 있는 경우, static으로 선언하지 않는다.
왜 자바에서 final 멤버 변수는 관례적으로 static을 붙일까?
상수 선언 시는 대부분 private static final을 사용한다. (+ static을 같이 붙이는 이유)
헛. 작은 부분이지만 조심스레 댓글 남깁니다.
static은 정적으로 관리되는 것은 맞지만, 컴파일타임에 값을 항상 보장하는 것은 아니에요.
컴파일러가 똑똑해서 일부는 컴파일 타임에 해석해서 보장해 주는 거예요.
이건 static final이더라도 마찬가지예요. 자바의 final은 어떤 식으로든 한 번만 대입이 된다는 게 보장되면 되고, 이건 다음 예시처럼 런타임에 값을 결정해서 대입하는 것을 방지하진 않거든요.