사내 프로젝트에서 동료의 코드를 같이 디버깅해주던 중, final 키워드가 클래스의 필드(field 또는 멤버 변수)로 쓰일 때의 특징을 깨닫게 되어 정리한다.
클래스의 필드를 final로 선언할 경우, 이 필드가 초기화되는 시점은 클래스의 부모 생성자(constructor)가 실행 된 이후 그리고 생성자(constructor) 메소드가 실행 되기 전이다.
동료의 코드에서 문제가 되었던 부분은 생성자의 인자로 받은 객체의 값을, final로 선언된 필드의 초기화에 사용하려고 했던 부분이었다.
class Judy {
Nick nick;
final String message = nick.say(); // nick이 null값으로 error가 발생한다
Judy(Nick nick) {
this.nick = nick;
}
}
위의 경우에는, final 필드인 message의 초기값에 nick의 값을 사용하려고 한다. 하지만, final 필드의 초기화는 생성자가 실행되기 전에 진행되기 때문에, 의도한 바와 다르게 초기화가 진행되는 시점에 nick 변수의 값은 null이 되어 에러가 발생한다.