Java - final이란?

김영한님의 Java 강의로 기초다지기 - final이란?

Posted by Warner on December 19, 2023

final

final 키워드는 이름 그대로 끝! 이라는 뜻이다.
변수에 final 키워드가 붙으면 더는 값을 변경할 수 없다.

public class FinalLocalMain {
    public static void main(String[] args) {
        // final 지역 변수
        final int data1;
        data1 = 10; // 최초 한번만 할당 가능
        data1 = 20; // 컴파일 오류
    }
}
  • final 을 지역 변수에 설정할 경우 최초 한번만 할당할 수 있다. 이후에 변수의 값을 변경하려면 컴파일 오류가 발생한다.
  • final 을 지역 변수 선언시 바로 초기화 한 경우 이미 값이 할당되었기 때문에 값을 할당할 수 없다.
  • 매개변수에 final이 붙으면 메서드 내부에서 매개변수의 값을 변경할 수 없다. 따라서 메서드 호출 시점에 사용된 값이 끝까지 사용된다.

final1.png

  • FiledInit 과 같이 final 필드를 필드에서 초기화 하는 경우, 모든 인스턴스가 다음 오른쪽 그림과 같이 같은 값을 가진다.
  • 여기서는 FieldInit 인스턴스의 모든 value 값은 10이 된다.
  • 필드 초기화는 필드의 코드에 해당 값이 미리 정해져있기 때문이다.
  • 모든 인스턴스가 같은 값을 사용하기 때문에 결과적으로 메모리를 낭비하게 된다. 이럴때 사용하면 좋은 것이 바로 static 영역이다.

static final

  • FieldInit.MY_VALUEstatic 영역에 존재한다. 그리고 final 키워드를 사용해서 초기화 값이 변하지 않는다.
  • static 영역은 단 하나만 존재하는 영역이다. MY_VALUE 변수는 JVM 상에서 하나만 존재하므로 앞서 설명한 중복과 메모리 비효율 문제를 모두 해결할 수 있다.

이런 이유로 필드에 final + 필드 초기화를 사용하는 경우 static을 붙여서 사용하는 것이 효과적이다.

상수

상수는 변하지 않고, 항상 일정한 값을 갖는 수를 말한다. 자바에서는 보통 단 하나만 존재하는 변하지 않는 고정된 값을 상수라 한다.

이런 이유로 상수는 static final 키워드를 사용한다.

자바 상수 특징

  • static final 키워드를 사용한다.
  • 대문자를 사용하고 구분은 _(언더스코어)로 한다.(관례)
    • 일반적인 변수와 상수를 구분하기 위해 이렇게 한다.
  • 필드를 직접 접근해서 사용한다.
    • 상수는 기능이 아니라 고정된 값 자체를 사용하는 것이 목적이다.
    • 상수는 값을 변경할 수 없다. 따라서 필드에 직접 접근해도 데이터가 변하는 문제가 발생하지 않는다.

final 변수와 참조

final은 변수의 값을 변경하지 못하게 막는다. 그런데 여기서 변수의 값이라는 것이 뭘까?

  • 변수는 크게 기본형 변수와 참조형 변수가 있다.
  • 기본형 변수는 10, 20 같은 값을 보관하고, 참조형 변수는 객체의 참조값을 보관한다.
    • final을 기본형 변수에 사용하면 값을 변경할 수 있다.
    • final을 참조형 변수에 사용하면 참조값을 변경할 수 없다.

final2.png 정리하면 참조형 변수에 final 이 붙으면 참조 대상을 자체를 다른 대상으로 변경하지 못하는 것이지, 참조하는 대상의 값은 변경할 수 있다.