프로그래밍Java 개발자

Java에서 final 메커니즘은 변수, 메서드 및 클래스에서 어떻게 작동하며, 이 수정자를 잘못 사용했을 때 어떤 예상치 못한 효과를 초래할 수 있습니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

Java에서 final은 다음에 사용됩니다:

  • 변수 — 초기화 후 변경 불가능함;
  • 메서드 — 자식 클래스에서 재정의할 수 없음;
  • 클래스 — 자식 클래스를 생성할 수 없음.

특징 및 세부사항:

  • final 변수는 선언 시 또는 생성자에서 초기화되어야 함;
  • final 참조는 참조를 변경할 수 없지만, 참조하는 객체는 변경할 수 있음 (immutable이 아닐 경우);
  • final 클래스(예: String, Math) 상속은 불가능함;
  • final 메서드는 자식 클래스에서 재정의할 수 없음.
final class A {} // class B extends A는 불가능함 class Parent { final void foo() { } } class Child extends Parent { // void foo() {} // 오류: foo를 반환할 수 없음 } final int COUNT = 10;

트릭 질문.

final 변수가 참조하는 객체의 상태를 변경할 수 있습니까?

답변: 네, immutable 객체가 아닐 경우 가능합니다. 예:

final List<String> names = new ArrayList<>(); names.add("Vasya"); // 허용됨 — 참조에 있는 객체는 변경 가능하지만 참조 자체는 변경할 수 없음 names = new ArrayList<>(); // 컴파일 오류

주제의 세부사항을 잘 모르고 생긴 실제 오류 사례.


이야기

로깅 시스템에서 유일한 final Logger를 코드 전체에 전달했으며, 객체가 완전히 보호된다고 생각했지만 공개 메서드를 통해 설정을 변경하여 전반적인 구성을 망가뜨렸습니다.

이야기

유틸리티 클래스에서 final 타입의 List 필드를 만들었고, 이후 이것을 외부로 반환하려고 했습니다. 외부 코드는 받아온 참조를 통해 목록의 내용을 편안하게 수정했습니다 — final이 이에 대해 보호하지 않습니다.

이야기

final 클래스에 기반한 외부 API를 확장해야 하는 문제가 발생했습니다. 이 때문에 확장이 불가능했고, 로직을 중복시켜 두 개의 독립적인 제품 브랜치를 유지해야 했고, 이는 마이그레이션을 복잡하게 만들었습니다.