Java final 키워드 - 상수 선언

final 키워드

Java 프로그램에서 final의 의미는 마지막으로 선언했기 때문에 수정할 수 없다는 의미이다.
즉, final가 부여된 요소는 초기화 이후에 수정할 수 없다.

final은 변수, 메서드, 클래스에 부여할 수 있는데, 어느 위치에 선언되는지에 따라 기능이 달라진다.

선언되는 위치 설명
Variable 변수의 데이터를 상수화하기 위해 사용하며, 값의 변경이 불가능해진다.
Method overriding이 불가능해진다.
Class 상속이 불가능해진다.

final 변수

final 데이터형 변수명 = ;

final이 부여되면 변수는 상수가 된다. 상수는 변하지 않는 수를 의미하며 상수로 선언한 변수는 값을 변경할 수 없다.

상수명은 관례적으로 영어 대문자와 언더 스코어(_)로 선언한다. 이 규칙은 구문 규칙이 아니지만 일반적인 명명을 따르는 것은 코드 가독성이라는 관점에서도 중요하다.
예를 들어, 다음은 문자열 유형 상수 GREETING_MSG를 선언하는 예제이다.

final String GREETING_MSG = "Hello World! Java.";

final 객체 변수인 경우

객체 변수의 경우 필드를 변경할 수 있지만, 객체 변수에 객체를 새로 생성하여 할당할 수 없다.

class SampleClass {     
    int a;  
}

public final class FinalSample {        
    public static void main(String[] args) {    
        final int RESULT = 10;
        RESULT++;
 
        final SampleClass SAMPLE = new SampleClass();
        SAMPLE.a = 10;
        SAMPLE.a = 15;
 
        SAMPLE = new SampleClass(); // 객체를 새로 생성하여 할당할 수 없다.
 
    }   
}

final 전역 변수인 경우

그리고, 보통은 전역 변수로서 finalstatic 키워드를 조합하여 여러 곳에서 공유하는 고정 값을 지정하여 사용한다.

public class FinalSample {      
    final int INDEX_LIMIT = 100;    
 
    public void display() { 
        System.out.println(INDEX_LIMIT);
        int[] arr = new int[INDEX_LIMIT];
        INDEX_LIMIT = 1005; // Error: 값을 다시 할당 할 수 없다.
    }   
}

final 인수인 경우

인수에도 final을 선언할 수 있다. 선언하면 그 인수는 사용되는 메서드에서는 값을 다시 할당 할 수 없게 된다.

public final class FinalSample {        
    public void finalTestMethod(final int a) {
        a = 10; // Error: 값을 다시 할당 할 수 없다.
    }   
}

final 메서드

final 메서드는 상속된 자식 클래스에서 다시 정의(overriding)를 할 수 없다.

class FinalMethodTest {
    int result = 10;    
    public final void printResult() {
        System.out.println(result);
    }
}

public class ExampleClass extends FinalMethodTest {
    @Override   
    public final void printResult() { // Error: 오버라이딩을 할 수 없다.
 
    }
}       

final 클래스

클래스에 final을 부여해 작성하면 상속을 할 수 없다.
final은 변수나 메서드를 재정의하면 기능이 정상적으로 동작하지 않는 클래스에 부여해 사용한다.

final class ExtendTest {    
    int a;
}

public class ExampleClass extends ExtendTest { // Error: ExtendTest를 상속할 수 없다.
    public static void main(String[] args) {
 
    }
}