Post

자바의 final 키워드

final 의미

  • 기본적으로 final 키워드를 붙이면 해당 값을 변경할 수 없도록 동작한다.
  • 즉, 단 한 번만 할당될 수 있는 Entity를 정의할 때 사용된다.
  • final 키워드는 final 변수, final 메서드, final 클래스 총 3가지에 적용할 수 있다.


final 변수

  • final 변수에서는 다시 네가지 경우로 세분화 시킬 수 있다.


원시 타입

  • 원시 타입 변수에 final로 선언하면 변경할 수 없는 상수값이 된다.
    1
    2
    3
    4
    
    public void test {
      final int x = 1;
      x = 3;  // 컴파일 단계에서 오류 발생
    }
    


객체 타입

  • 객체 변수에 final로 선언하면 다른 참조 값으로 변경할 수 없다.
  • 객체 자체가 불변하다는 것은 아니므로 객체 안의 필드값은 변경 가능하다.
    1
    2
    3
    4
    5
    6
    
    public void test {
      final Pet pet = new Pet();
      pet = new Pet(); // 컴파일 단계에서 오류 발생
    
      pet.setAge(5); // 객체 필드는 변경 가능
    }
    


메서드 인자

  • 메서드 인자에 final 키워드를 붙이면 메서드 안에서 변수값을 변경할 수 없다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    public class Pet {
      int age;
        
      public void setAge(final int age) {
          age *= 10; // 컴파일 단계에서 오류 발생
    
          this.age = age;
      }
    }
    


클래스 멤버 변수

  • 클래스의 멤버 변수에 final로 선언하면 상수값이 되거나 객체의 생성과 동시에 초기화되어야 하는 값으로 사용된다.
  1. instance final 멤버 변수는 다음과 같은 상황에 할당이 가능하다.
    • 값과 함께 선언시
      1
      2
      3
      
        public class Pet {
            final int age = 5;
        }
      
    • 인스턴스 초기화 블록에서
      1
      2
      3
      4
      5
      6
      7
      
        public class Pet {
            final int age;
      
            {
                age = 5;
            }
        }
      

      인스턴스 초기화 블록은 인스턴스가 생성될 때마다 생성자가 실행되기 전에 실행된다.

    • 생성자 메서드에서
      1
      2
      3
      4
      5
      6
      7
      
        public class Pet {
            final int age;
      
            public Pet(){
                age = 5;
            }
        }
      
  2. static final 멤버 변수는 다음과 같은 상황에 할당이 가능하다.
    • 값과 함께 선언시
      1
      2
      3
      
        public class VariableConstant {
            static final int INT_SIZE = 4;
        }
      
    • 정적 초기화 블록에서
      1
      2
      3
      4
      5
      6
      7
      
        public class VariableConstant {
            static final int INT_SIZE;
      
            static {
                INT_SIZE = 4;
            }
        }
      

      정적 초기화 블록은 클래스 로드 시 한번만 블록이 실행된다.


final 메서드

  • 메서드를 final로 선언하면 상속받은 클래스에서 오버라이드가 불가능하게 된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Pet {
    String name;

    public final void petName() {
        System.out.println("my name is " + this.name);
    }
}

public class Dog extends Pet {
    
    public Dog(String name) {
        this.name = name;
    }

    @Override   // 컴파일 단계에서 오류 발생
    public final void petName(){
        System.out.println("hello");
    }
}


final 클래스

  • 클래스에 final 을 선언하면 상속 자체가 안된다.
  • 인스턴스 생성은 가능하다.
  • 인스턴스 생성은 불가하고 상속만 가능한 abstract 키워드와 반대라고 볼 수 있다.
1
2
3
4
5
6
public final class Constants {
    public static final int INT_SIZE = 4;
}

public class AdditionalConstants extends Constants {    // 컴파일 단계에서 오류 발생
}


누군가가 물어본다면

final 키워드는 한번 할당한 후 값을 변경하지 않도록 하기 위해 사용합니다.
This post is licensed under CC BY 4.0 by the author.