final
키워드는 한번만 할당 가능하다는 선언.
즉, 재할당하려고 하면 컴파일 오류가 발생하여 바로 확인이 가능하다.
사람은 항상 실수를 하기 때문에, 실수를 예방하는 것이 중요하다. 값에 대한 검증이 따로 필요하지 않고 로직 구현에만 집중할 수 있고 심리적인 안정감을 얻기 위해서라도 final 키워드 사용은 중요하다.
예를 들어, 아래와 같은 코드 상황을 보자. a 부터 b 까지의 수를 더하고 싶은 상황이다.
public int addFromTo(final int a, final int b){
int sum = 0;
for (int i=a;i<b;i++){
sum += i;
}
return sum;
}
위 코드는 개발자의 실수로 b를 포함하지 않았다. 원래 의도는 for(int i=a;i<=b;i++) {...}
이와 같이 표현했어야 할 것이다. 그러나 final 객체가 아닌 sum
과 i
변수가 이런 실수의 여지를 남겨두었다.
아래와 같이 final 선언된 변수만으로 코드를 구성한다면 위와 같은 실수를 예방할 수 있을 것이다.
public int addFromTo(final int a, final int b){
return addFromOneTo(b) - addFromOneTo(a-1);
}
private int addFromOneTo(final int n){
return (n * (n+1)) / 2;
}
한 번 생성되면 상태를 수정할 수 없는 객체를 뜻한다.
아래와 같은 상황을 보자. 멀티 쓰레드 환경
에서 변수 money
에 10000원과 500원을 넣는 상황이다.
멀티 쓰레드 환경
에서는 위와 같이 10000원이 할당되고, 또 500원이 할당되는 과정을 장담할 수 없게 된다. 동시의 상황으로 진행되면 10000원이 할당되고 그 사이에 500원이 할당되어, 최종 결과값을 조회할 때 500원으로 덮어 씌워진 결과를 반환하는 문제가 발생할 수 있다.
바로 이 쓰레드 동기화 문제 방지
가 불변 객체를 사용해야 하는 이유이기도 하다.
위와 같은 코드로 값을 더하는 메서드 자체를 호출할 때마다 새로운 불변 객체를 반환하게
하면 문제를 해결할 수 있다.
"불변 객체를 사용해라. 성능 상의 단점은 미미하다. 현대 컴퓨터의 성능을 무시하지 마라." - 제이슨
"불변 객체는 간단하고 신뢰성 있는 코드를 만들기 위한 전략이다" - 오라클 자바 튜토리얼
"불변 객체는 가변 객체보다 설계하고 구현하고 사용하기 쉬우며, 오류가 생길 여지도 적고 훨씬 안전하다" - 이펙티브 자바