final
final 키워드는 변수(variable), 메서드(method), 또는 클래스(class)에 사용될 수 있다.
어떤 곳에 사용하냐에 따라 다른 의미를 가지며, 어디에 붙던 공통적으로는 제한한다는 성격을 가지고 있다.
변수(variable)
원시 타입
원시 변수에 final을 붙이면 변경할 수 없는 상수 값이 된다.
그렇기에 초기화 값은 필수적이며, 변경 불가능 한 점은 그 변수의 값에 한정된다.
final int a = 1;
//a = 2; 변경 불가
객체 타입
객체 변수 final 선언의 경우 그 변수에 다른 참조 값을 지정할 수 없다.
한번 쓰여진 변수는 재변경이 불가능하지만, 객체의 속성 자체는 변경이 가능하다.
final Member member = new Member();
// member = new Member(); 다른 객체로 변경 불가
member.id(2); // 객체 속성은 변경할 수 있다.
메서드 인자
메서드 인자에 final 키워드를 붙이면, 메서드 안에서 변수값을 변경할 수 없다.
public class Kitty {
int age;
public void setAge(final int age) {
// age = 1; final 인자는 메서드 안에서 변경 불가
}
}
물론 메서드 안에서 변수 값을 변경할 수 없다는 것은 밖에서는 가능하다.
조금 더 들어가자면 아까 원시, 객체 타입에서 stack 메모리 영역에서 변경이 불가능해지지만, 객체 타입의 경우 가리키고 있는 객체 내부의 값은 stack 영역이 아닌 heap 영역이기 때문에 변경이 가능한 것
마찬가지로 메서드 인자의 경우도 Kitty라는 메모리 내부에 제한하는 것이라 그 밖에서는 변경이 가능하다는 점이다.
메서드(method)
메서드의 경우 final이 붙으면 override를 제한하게 된다.
먼저 요약해서 설명하자면 상속 받은 클래스에서 해당 메서드를 수정하지 못하게 메서드에 final을 붙이는 것
즉, 구현한 코드의 변경을 원하지 않을 때 사용한다.
public class Pet {
public final void isSound() {
System.out.println("meow");
}
}
public class Cat extends Pet {
// final 메서드는 override 불가능
public void isSound() {
}
}
클래스(class)
클래스에 final을 선언하면 상속이 불가능한 클래스가 된다.
public final class Pet {
}
// public class Cat extends Pet { } -> 자체가 안된다.