자바 언어에서 final은 오직 한 번만 할당할 수 있는 entity 를 정의할 때 사용된다.
final 로 선언된 변수가 할당되면 항상 같은 값을 가진다. 만약 final 변수가 객체를 참조하고 있다면, 그 객체의 상태가 바뀌어도 final 변수는 매번 동일한 내용을 참조한다.
final 키워드는 클래스, 필드, 메소드, 지역변수, 파라미터에 적용할 수 있다.
클래스에 final 은 상속을 허용하지 않는다.
메소드의 final 은 오버라이딩을 허용하지 않는다.
필드, 지역변수, 파라미터에 final을 적용하면 한번 초기화 한 이후에는 다른 값으로 변경할 수 없다.
final 필드의 초기화 방식은 필드 선언 시점의 초기화, 초기화 블록, 생성자를 통한 초기화 방법 3가지가 있다.
public class FinalExam {
private final String message = "Final Message"; // (1)
private final String message;
{
message = "Final Message"; // (2)
}
public FinalExam(String message) {
this.message = message; // (3)
}
public final void showMessage() {
System.out.println(message);
}
// final 로 선언된 인자값
public void showMessage(final String message) {
// message = "New Message!";
// Cannot assign a value to final variable 'message'
System.out.println(message);
}
}
메소드를 final 로 선언하면 상속받은 클래스에서 오버라이딩이 불가능하다. Dog 객체는 Pet 의 makeSound()
메소드를 재정의할 수 없다.
public class Pet {
public final void makeSound() {
System.out.println("ahaha");
}
}
public class Dog extends Pet {
// final로 된 메소드는 override 할 수 없음
public void makeSound() {
}
}
클래스에 final 을 선언하면 상속 자체가 불가능하다. 그냥 클래스 그대로 사용해야 한다.
public final class FinalClass {
...
}
// final 클래스로 선언되어 상속할 수 없음
public class OtherClass extends FinalClass {
...
}
자바에서 기본적으로 제공하는 라이브러리 클래스는 final 을 사용함
java.lang.System, java.lang.String ...
final 은 최종이라는 의미.
변수, 메소드, 클래스 각각 어디에 붙냐에 따라 다르지만 개념은 같다.
불변성, 상수값 유지, 상속과 오버라이딩의 방지 등 이러한 특성들은 소프트웨어 개발에서 버그를 줄이고 코드를 유지보수하기 쉽게 만들어준다.
따라서 final 키워드는 코드의 안정성과 예측 가능성을 높이기 위한 강력한 도구로 사용된다.