Java에서 final 키워드는 말 그대로 마지막이라는 의미로 통용된다.
뭐가 마지막이냐?
값을 마지막으로 지정하다는 뜻이다.
final 키워드는 변수에 사용 가능하며,
final을 사용해서 선언한 변수는 최초 초기화 이후 변경이 불가능하다.
몇 가지 규칙이 있으니 알아보자.
final 키워드를 사용하여 선언한 지역 변수는
최초 1회만 초기화가 가능하다.
public void method finalMethod() {
final int num = 10;
num = 20; // 불가
}
final로 선언한 필드는
생성자로 최초 1회 초기화한 후, 더 이상 변경할 수 없다.
class Clazz {
final int number;
public Clazz(int number) {
this.number = number;
}
}
public void method changeMethod() {
Clazz clazz = new Clazz(10);
clazz.number = 20; // 변경 불가
final로 선언한 필드를
생성자가 아닌 필드에서 초기화 할 경우,
이후 생성자로도 초기화가 불가능하다.
class Clazz {
final int number = 10;
public Clazz(int number) {
this.number = number; // 불가
}
}
final을 사용한 필드를 필드에서 초기화 할 경우,
생성자로도 더 이상 바꿀 수 없게 된다.
그 말인 즉슨, 변경할 수 없는 값을 객체 생성 마다 계속 생성해주어야 한다는 것이다.
아주 비효율적인 상황이다.
class Clazz {
final int number = 10;
}
public void finalMethod() {
Clazz clazz1 = new Clazz(); // clazz1 인스턴스 내부에 number 인스턴스 필드 생성
Clazz clazz2 = new Clazz(); // clazz2 인스턴스 내부에 number 인스턴스 필드 생성
}
이럴 땐, 메서드 영역에서 관리하여 최초 1회만 생성할 수 있도록
static 키워드를 사용하여 선언한다.
메서드 영역에 대한 정보는 다음을 참고하자
class Clazz {
static final int number = 10; // 최초 1회 생성하여 메서드 영역에서 관리
}
상수란 변하지 않는 고정된 단 하나만 존재하는 값이다.
변하지 않으려면? → final
하나만 존재하려면? → static
class Clazz {
static final int MAX_SCORE = 100;
final 키워드를 사용하여 선언된 객체는
더 이상 참조 값을 변경할 수 없다.
final 키워드를 사용하지 않은 내부 필드는 변경이 가능하다.
class Clazz {
public int number = 0;
}
publc void classMethod() {
Clazz clazz = new Clazz();
clazz = new Clazz(); // 불가, 참조 값을 변경할 수 없음
clazz.number = 1; // 가능
내가 사용하는 필드가 어떻게 사용되는지 검토하고
상수로 처리해야 할 지,
그리고 그 상수를 어디서 관리해야할 지 등을 고민해보는 것이 좋겠다.