[김영한의 실전 자바 기본편] - final

jkky98·2024년 4월 26일
0

Java

목록 보기
8/51

final

final은 수정자이다. final 해석 그대로 "끝"을 나타내는 뜻이며, 변수에 final 키워드가 붙으면 처음 값이 초기화되고 바꿀 수 없다. 이후 값을 변경하려 하면 컴파일 오류가 발생한다.

만약 인스턴스 변수에 final을 붙여 10으로 항상 초기화 시킨다고 생각해보자.

private final int valueHold = 10;

우리는 하나의 클래스에 대해 여러 인스턴스를 생성한다.

힙 영역에 존재하는 여러 인스턴스들에 항상 10이 담길 것이다. 모든 인스턴스들이 동일하게 변화하지 않는 10을 사용할 수 있다.

객체를 생성할 때마다 서로 다른 인스턴스 변수 값이 존재할 수 없다면, 어딘가 한 공간에서만 고정 변수 = 10이라고 구축해놓고 생성된 여러 객체들은 이것을 쓰고싶을 때마다 가져다 쓰면 되지 않을까? 이러한 중복문제를 피하기 위해 우리는 static까지 추가한 static final을 활용한다.

static final

static final로 클래스 변수를 final화 한다. static final로 생성된 필드는 JVM의 시작부터 끝까지 유지될 것이다. 이쯤되면 "상수"의 개념이 생각날 것이다. 상수를 구현할 때 java에서는 static final을 활용하여 사용한다.

상수의 특징

  • static final 키워드 사용
  • 이름규칙 : 대문자 사용, 구분은 언더바(_)로 한다.
  • 직접 접근해서 사용해도 상관 없다. 어차피 final로 인해 수정이 불가능하다. 그러므로 private보단 public쪽으로 많이 사용한다.
public static final double PI = 3.14;
public static final int HOURS_IN_DAY = 24;

상수의 필요성

package final1;

public class ConstantMain1 {
    public static void main(String[] args) {
        System.out.println("도서관 최대 수용인원 : " + 155);
        int currentUserLibrary = 154;
        enterLibrary(currentUserLibrary++);
        enterLibrary(currentUserLibrary++);
        enterLibrary(currentUserLibrary++);
    }
    private static void enterLibrary(int currentUserLibrary) {
        System.out.println("현재 입실자 수 : " + currentUserLibrary);
        if (currentUserLibrary < 155) {
            System.out.println("도서관에 입실했습니다");
        } else {
            System.out.println("만석입니다.");
        }
    }
}

위 도서관 코드는 155명 정원에 현재 인원 154명이니 3명이 enter한다면 처음 한명만 들어올 수 있고 나머지 두명은 if문에 의해 가로막힌다.

만약 도서관 증축 이후 155라는 최대 수용 수를 바꿔주어야 한다면 우리는 위의 코드에서 155를 원하는 새로운 수로 바꿔줄 것이다. 하지만 위의 예시 코드와 다르게 실제 서비스 코드는 굉장히 복잡하고 클 것이다. 이러한 시스템에서 어떤 파일들에서 155가 사용됬는지 모른다. 최대 수용수를 수정하기 위해 155란 값을 모두 찾아내어 수정해야 한다.

만약 Constant란 파일에 모든 상수를 관리한다고 가정하고 public static final int MAX_COUNT_LIBR = 155; 로 설정해놓는다고 하자. 모든 파일에서 필요시 이 상수를 가져다 쓴다면 우리는 Constant파일에서의 해당 상수만 수정해주면 된다.

package final1;

public class ConstantMain1 {
    public static void main(String[] args) {
        System.out.println("도서관 최대 수용인원 : " + Constant.MAX_COUNT_LIBR);
        int currentUserLibrary = 154;
        enterLibrary(currentUserLibrary++);
        enterLibrary(currentUserLibrary++);
        enterLibrary(currentUserLibrary++);
    }
    private static void enterLibrary(int currentUserLibrary) {
        System.out.println("현재 입실자 수 : " + currentUserLibrary);
        if (currentUserLibrary < Constant.MAX_COUNT_LIBR) {
            System.out.println("도서관에 입실했습니다");
        } else {
            System.out.println("만석입니다.");
        }
    }
}

final 변수와 참조

만약 final 필드가 참조형이라면 객체는 고정이지만 참조형은 변수에 할당된 주소만 바꿀 수 없는 것이기에 주소로 접근해서 사용하는 필드들은 이용하는 것에 문제가 없다. 이를 잘 생각해서 사용하도록 하자.

profile
자바집사의 거북이 수련법

0개의 댓글