자바의 final 키워드

자바에서 사용하는 final 키워드는 무엇일까? 어떻게 활용할 수 있는지 알아보자

#java #final


final

final 키워드는 클래스, 메서드, 변수에 사용할 수 있는데 의미는 단어 그대로 마지막이라는 뜻이다. 이 키워드를 사용하게 되면 어떻게 동작하는지 알아보자.


final과 클래스

final 키워드를 클래스에 사용하게 되면 다른 클래스가 상속할 수 없게 된다. 이러한 점은 보안적인 측면을 고려한 부분이라고 생각할 수 있다. 대표적으로 java.lang.String 클래스도 final 이다.

final class MadPlay {
    // ...
}

class MadClass extends MadPlay { // 컴파일 오류
    // ...
}

상속을 할 수 없으니 재정의(Override)는 물론 불가능하다. 시도조차 할 수 없다. 하지만 반대로 final 클래스는 다른 클래스를 상속할 수 있다.

class MadMan {
    // ...
}

final class MadPlay extends classMan {
    // ...
}


final과 메서드

메서드에 final 키워드를 붙이게 되면 재정의(Overriding)을 할 수 없다.

class MadClass {
    public final void sayHi() {
        // ...
    }
}

public class MadPlay extends MadClass {
    // 컴파일 오류 발생
    // cannot override... overridden method is final    
    public void sayHi() {
        // ...
    }
}


final과 변수

final 키워드가 적용된 변수는 상수의 역할을 하게 된다. 값을 변경하려고 하면 컴파일 오류가 발생한다. 즉 초기화는 1회만 가능합니다. 따라서 보통 final 변수는 선언과 동시에 초기화한다.

public class MadPlay {
    final int MAX_ARRAY_SIZE = 5;

    public void someMethod() {
        int[] array = new int[MAX_ARRAY_SIZE];

        // 컴파일 오류
        MAX_ARRAY_SIZE = 10;
    }
}

하지만 final 멤버 변수가 무조건 선언과 동시에 초기화해야 하는 것은 아니다. 아래 코드를 보자.

public class Person {
    private final String name;

    // 단, 기본 생성자를 만드는 경우 아래처럼 초기화가 필요하다.
    public Person() {
        this.name = "kimtaeng";
    }

    public Person(String name) {
        this.name = name;
    }
}

생성자를 통해서 final로 선언된 멤버 변수를 초기화 했다. 이처럼 반드시 선언과 동시에 초기화가 필요한 것은 아니다.


그런데 왜 대부분의 상수는

대부분의 final 키워드를 이용한 상수 필드를 사용할 때는 아래와 같이 사용한다. 프로젝트 코드 내에서 전체적으로 공유하여 사용할 수 있게 하기 위함이다.

class GradeHelper {
    public static final String MAX_GRADE = "A+";
}

그런데 왜 관례적으로 public static 일까? 우선, public은 전체 공개용을 뜻한다. 다른 클래스, 심지어 다른 패키지의 클래스에서도 접근할 수 있음을 뜻한다.

static은 메모리 할당을 컴파일 시간에 한다. 그러니까 인스턴스가 생성될 때마다 새로운 메모리를 할당하는 것이 아니라 클레스 레벨에서 단 한번만 할당함을 뜻한다. 그렇기 때문에 의미와 용도가 고정적인 값에 사용하면 알맞다. 예를 들어, 최고 학점이 A+인 것처럼 말이다. S 학점이 있는 곳도 있을 수 있으려나…





댓글을 남기시려면 Github 로그인을 해주세요 :D