[JAVA] final 키워드 정복하기!

2025. 10. 16. 23:43·Java & Kotlin

들어가며

객체지향적인 코드를 위해!! 수많은 검색과.. 기술블로그 서칭과 코드를 보며 final을 자주 사용하는 것을 볼 수 있었다. final은 불변의 의미로 상수화 시킬때만 쓰는 정도로 알고 있었는데, 메서드랑 심지어는 클래스에도 붙힌다! 처음 봤을 때 정말 이게 뭐지??? 싶었다. 그래서 이번 기회에 정리해보고 실제 문제 풀이에서 어떻게 적용했는지 알아보자!

 

 

본론으로

final은 어디에 붙이느냐에 따라 의미가 달라지지만, 공통적으로 “변경 가능성을 제한” 한다는 뜻이다. 잘 사용하기만 한다면 유지보수, 안전성, 동시성 측면에서 큰 힘이 된다.


1) 변수에 final — “참조 자체를 못 바꾼다”

  • 기본형: 값 재할당 금지.
  • 참조형: “참조” 재할당 금지(= 다른 객체를 가리키게 못함). 객체의 내부 상태 변경은 가능.
  • 초기화 규칙: 반드시 한 번은 초기화되어야 함(지역 변수는 사용 전, 필드는 생성자/초기화 블록/선언 시).
final int n = 3;        // 재할당 불가
final List<String> a = new ArrayList<>();
a.add("ok");            // 내부 상태 변경은 가능
// a = new ArrayList<>(); // 컴파일 에러 (참조 재할당 불가)

 

내부 상태가 변경이 되는점은 좀 찜찜하다. 진짜 “불변(immutable)”을 원하면 List.of(...), Collections.unmodifiableList(...), 레코드/불변 클래스 설계, 방어적 복사까지 동원해야 한다. -> 이 부분은 Collection의 복사방법이라는 주제로 따로 다룰 예정이다.

어쨋거나! 변수에 final 붙이면 값,참조값 재할당이 불가능하게 된다.


2) 메서드에 final — “오버라이드 금지”

  • 서브클래스가 바꾸면 안 되는 템플릿/핵심 규칙을 고정하려고 할 때. 
  • 보안규칙을 깨뜨릴 여지를 줄일 때.
class Base {
    public final void validate() { /* 개별 정책 고정 */ }
}
class Child extends Base {
    // @Override void validate() { ... } // 컴파일 에러
}

 


3) 클래스에 final — “상속 금지”

  • 유틸 클래스, 값/불변 객체, 보안 민감 타입, 혹은 “설계상 상속을 고려하지 않는” 클래스를 잠그는 데 적합.
  • String, Integer 같은 래퍼/값 타입이 대표적.
public final class ConsoleReader {
    public static String readMessage() { ... }
}

 

나 이 클래스 상속하게 해줘. 안 돼.

 

"상속을 허용할 설계인지?”를 먼저 결정하자. 상속 확장 포인트가 없고 상태도 없으며, 정적 유틸 메서드만 제공한다면 final이 적합하다.

-> 정말 확실한 의도를 갖고 final을 적용하자.


4) 매개변수에 final — “매개변수 재할당 금지”

언제 쓸까?

  1. 재할당 실수를 방지하고, “이 인자는 읽기 전용” 의도를 드러내고 싶을 때.
public String normalize(final String input) {
    // input = input.trim(); // 컴파일 에러 (재할당 금지)
    return input == null ? "" : input.trim();
}

 

 

final이 붙은 곳에 따라 의미하는 바가 이렇게나 달라진다! 잘 기억하고 의도가 명확하게 잘 활용하자!


5)  내 코드에 적용 - 왜 ConsoleReader를 final Class로 지정하였는가?

아래 코드를 보자 나는 실질적인 입력 호출은 ConsoleReader가 하고 View계층이 이를 호출하는 흐름으로 설계했다! 이는 왜냐하면 터무니 없는 빈값 호출은 콘솔쪽에서 Validation하는 것이 더 옳다고 생각을 하였다. 그리고 final을 붙힌 이유는 아래 글을 보자.

public final class ConsoleReader {
    public static String readMessage() {
        return Validator.validate(Console.readLine());
    }
    private static class Validator {
        static String validate(String message) { return validateBlank(message); }
        private static String validateBlank(String message) {
            if (message.isBlank()) throw CustomException.from(ErrorMessage.BLANK_INPUT_ERROR);
            return message;
        }
    }
}

 

이 클래스는 상속할 일이 없다. 이유는 명확하다.

  • 상태가 없다: 인스턴스 필드가 없고, 정적 메서드로 한 가지 일(콘솔 입력 읽기 + 빈 값 검증)만 한다.
  • 확장 포인트가 없다: 동작을 다형성으로 바꾸는 순간, 콘솔 IO 추상화/주입 설계가 필요해진다(그건 별도의 인터페이스로 분리해야 할 차원의 문제).

    한 줄 요약: 기능상 확장 대상이 아니고, 상태도 없고, 정적 유틸 성격이 강하므로 final이 자연스러운 선택으로 판단된다.

 

마무리하며

잘 제한된 코드는? 좋은 코드다~

이 말씀은 김영한님의 자바 강의를 들어본 사람이라면 꽤나 들어본 표현일 것이다! 나는 많은 분들이 final을 적재적소에 과감하게 사용하시는 것을 보고 위의 문장이 떠올랐다.

나의 의도를 명확하게 하고 잘 활용해보자!

'Java & Kotlin' 카테고리의 다른 글

[JAVA] 정규 표현식, Pattern 클래스로 쉽게 이용해보자! (Pattern.quote()를 중점적으로)  (0) 2025.10.17
[JAVA] 일급 콜렉션을 이용하여 상태와 로직을 따로 관리하자!  (0) 2025.10.17
[JAVA] 정적 중첩 클래스를 활용하여 계층간 독립적인 Validation을 적용해보자  (0) 2025.10.16
[JAVA] 정적 팩토리 메서드(Static Factory Method)란? (버거 먹고싶은 작성자와 스프링의 반환 방식을 곁들인)  (0) 2025.10.16
[JAVA] String trim() 메서드 : 문자열의 앞뒤에 있는 모든 공백 문자를 제거해주는 아주 좋은친구 소개  (0) 2024.11.09
'Java & Kotlin' 카테고리의 다른 글
  • [JAVA] 정규 표현식, Pattern 클래스로 쉽게 이용해보자! (Pattern.quote()를 중점적으로)
  • [JAVA] 일급 콜렉션을 이용하여 상태와 로직을 따로 관리하자!
  • [JAVA] 정적 중첩 클래스를 활용하여 계층간 독립적인 Validation을 적용해보자
  • [JAVA] 정적 팩토리 메서드(Static Factory Method)란? (버거 먹고싶은 작성자와 스프링의 반환 방식을 곁들인)
노을을
노을을
진인사대천명
  • 노을을
    노을의 개발일기장
    노을을
  • 전체
    오늘
    어제
    • All (61) N
      • Java & Kotlin (16)
      • Spring (3) N
      • Problem Solve (13) N
      • Computer Science (0)
      • Infra (1)
      • DB (2)
      • Various Dev (23)
        • 우아한테크코스 (9)
        • Git&Github (2)
        • Unity (12)
      • Book (1)
      • Writing (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    자바
    백준
    우아한테크코스
    개발
    합격
    오픈미션
    게임개발
    코딩테스트
    스프링
    유니티
    코딩
    알고리즘
    우테코
    프리코스
    티스토리챌린지
    코테
    8기
    java
    github
    개발자
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
노을을
[JAVA] final 키워드 정복하기!
상단으로

티스토리툴바