Post

[Java] final 키워드 정리

📝 개요


자바에서 final 키워드는 변경할 수 없다는 의미를 가지며,
변수, 메서드, 클래스에 각각 다르게 사용된다.

final 키워드 종류를 트리 구조로 한번 알아보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final
├── 변수 (Variable)
│   ├── 지역 변수 (Local Variable)
│   │   └── 메서드 내부에서 선언, 재할당 불가
│   │
│   ├── 매개변수 (Parameter)
│   │   └── 메서드 인자에서 값 변경 불가
│   │
│   ├── 인스턴스 변수 (Instance Field)
│   │   ├── 선언 시 초기화
│   │   └── 생성자에서 초기화
│   │
│   └── 클래스 변수 (Static Final Field)
│       └── 상수(Constant), 클래스 단위로 공유
│
├── 메서드 (Method)
│   └── 오버라이딩(재정의) 불가
│
└── 클래스 (Class)
    └── 상속 불가 (Subclass 불가능)

1️⃣ 변수에 사용된 final


✅ 지역 변수 (Local Variable)

  • 메서드 내부에서 선언된 변수
  • 한 번 값이 할당되면 변경이 불가능하다.
1
2
3
4
void greet() {
    final String message = "Hello";
    message = "Hi"; // ❌ 오류
}

✅ 매개변수 (Parameter)

  • 메서드의 인자 값이 내부에서 변경되지 않도록 보호
1
2
3
void printName(final String name) {
    name = "Tom"; // ❌ 오류
}

✅ 인스턴스 변수 (Instance Field)

  • 클래스의 필드에 사용
  • 선언과 동시에 초기화하거나, 생성자에서 한 번만 초기화 가능
1
2
3
4
5
6
7
class User {
    final String id;

    User(String id) {
        this.id = id; // ✅ 생성자에서 한 번 초기화
    }
}

2️⃣ 메서드에 사용된 final


✅ 메서드 오버라이딩 방지

  • 자식 클래스가 해당 메서드를 오버라이드할 수 없음
1
2
3
4
5
6
7
8
9
class Parent {
    final void show() {
        System.out.println("Hello");
    }
}

class Child extends Parent {
    // void show() { } // ❌ 오류
}

3️⃣ 클래스에 사용된 final


✅ 클래스 상속 방지

  • 이 클래스를 다른 클래스가 상속할 수 없음
1
2
3
4
5
final class Animal {
    void sound() { System.out.println("Sound"); }
}

// class Dog extends Animal { } // ❌ 오류

💬 마무리

final 키워드는 단순히 값을 고정하는 것 이상으로,
코드 안정성과 예측 가능성을 높이는 데 매우 유용하다.

하지만 final을 용도에 맞지 않게 너무 많이 사용하면
변경이 불가능해져 확장성과 유연성이 떨어지게 되므로
팀 프로젝트나 라이브러리 개발 시, 꼭 필요한 곳에만 신중하게 사용하여야 한다!