개요
어김없이 우아한 테크 코스 이야기를 안할 수가 없는데요,, 프리 코스를 진행하면서 변화한 부분 중 하나는 final 키워드를 사용함으로써 불변성에 대해 많은 고민을 한 것입니다. 하지만 final 키워드는 단지 “변경하지 못하게 막는다” 라고 정의할 수는 없는데요, 이번 포스팅에서는 자바의 final 키워드에 대해 조금 더 자세히 알아보도록 하겠습니다!
final 키워드란
In the Java Programming language, the final keyword is used in several contexts to define an entity that can only be assigned once.
위키피디아의 설명을 참고하면 자바 키워드는 개체가 오직 한 번만 할당되도록 설정하는 것입니다.
예를 들어 다음과 같은 경우는 오류가 발생합니다. 이미 할당된 final 변수의 값을 변경하려고 시도했기 때문이죠.
@Test
void final은_값을_변경할_수_없다(){
final int number = 3;
number = 5; // 에러 발생
}
Java
복사
final 키워드는 마찬가지로 메소드에 적용할 수도 있습니다. final 키워드가 붙은 메서드는 오버라이딩이 안되는데요, 예제를 보며 함께 살펴보겠습니다.
public class Person {
public final void eat() {
System.out.println("냠냠");
}
}
public class Student extends Person {
@Override
public void eat(){
System.out.println("우걱우걱"); // 에러 발생
}
}
Java
복사
마지막으로 클래스에 선언한다면 상속이 불가능합니다.
final의 오해
final 키워드는 재 할당을 못한다는 것이지 값을 변경하지 못한다는 것은 아닙니다. final 키워드가 사용된 변수는 그 참조값을 변경할 수 없지만, 그 변수가 참조하는 객체의 상태는 변경할 수 있습니다. 즉, final로 선언된 객체의 내부 필드 값을 변경하는 것은 가능합니다. 이는 누누이 말했던 불변성이 final이 객체 자체가 아닌, 객체의 참조에 대해서만 적용되기 때문입니다.
예를 들어, final로 선언된 리스트에 새로운 요소를 추가하거나 제거하는 것은 가능합니다.
@Test
void 리스트_내부_값의_변경은_가능하다(){
final List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
list.set(1, "Java");
}
}
@Test
void 리스트_참조_변경_시_예외가_발생한다(){
final List<String> list = new ArrayList<>();
list = new ArrayList<>(); // 에러 발생
}
Java
복사
위 예제 처럼 리스트 자체를 다른 리스트로 변경하는 것은 불가능합니다.
이러한 성질로 인해 final은 변경 불가능한 객체를 만드는 데에만 사용되는 것이 아니라, 객체의 무결성을 유지하는 데에도 중요한 역할을 합니다.