Java에서는 불변성을 확보할 수 있도록 final 키워드를 제공하고 있습니다.
이 Final 키워드가 사용되는 4가지 경우를 살펴봅시다.
변수에 final 키워드를 붙이며 첫 초기화 이후, 재할당이 불가능합니다.
final int num = 11;
num = 17; // 재할당 불가능
메소드에 final 키워드를 붙이며 해당 메소드가 있는 클래스를 상속받는 하위클래스 해당 메소드를 재정의할 수 없습니다.
public class Person{
String name;
int age;
//...생략
public final void addAge(){
this.age++;
}
}
public class Student extends Person{
public void addAge(){
//함수를 재정의할 수 없다고 에러 발생
}
}
시스템의 코어부분에서 변경을 원치 않는 메서드에 많이 final을 붙이는 것을 볼 수 있습니다.
클래스에 final 키워드를 붙이면 그 클래스는 상속할 수 없습니다. 더 이상 확장되면 안되는 클래스에 final 키워드를 사용합니다. 상속받을 수 없기 때문에 모든 메소드들은 재정의할 수 없습니다.
public final class A {
//..생략
}
public class B extends A{
//클래스 A는 final 클래스이므로 상속 불가능
//에러 발생
//..생략
}
우리가 잘 알고 있는 String클래스에도 final 키워드가 붙어있습니다.
변수, 메소드, 클래스 뿐만아니라 메소드 내의 매개변수를 final로 설정할 수 있습니다. final 키워드가 붙은 매개변수는 함수내에서 재할당이 불가능합니다.
public void getNumber(final int num){
num = 3; // error
}
하지만 아래와 같이 final 키워드가 붙은 객체를 매개변수로 받는다면, 객체내용을 변경하는 것이 가능합니다.
public void getAge(final Person person){
person.setName("가나다");
//person = new Person("가나다",22);
}
이는 final 키워드가 원시타입이 아닌 참조타입인 경우, 해당 객체를 가리키는 주소값을 변경할 수 없도록 한다는 의미이기 때문에 객체에 final을 붙이면 객체 이름으로 선언, 재할당을 할 수 없습니다.
그래서 객체를 변경하는게 아닌 객체의 값을 변경하는 행동은 허용이 되는 것입니다.
그렇다면 이 객체의 값도 변경할 수 없도록 하려면 객체의 필드 중 불변성을 유지하고 싶은 필드에 final을 달면 됩니다.
public class Person{
final String name;
int age;
//...생략
}
정리 | |
---|---|
변수 | 최초 초기화 시 재할당 불가능 |
메소드 | 상속 시 재정의 불가능 |
클래스 | 상속 불가능 |
인자(Args) | 메소드내에서 재할당 불가능 매개변수가 레퍼런스 타입인 경우 객체 이름으로 선언 불가능 |