[개발 일기] 2025.04.16 - 클래스가 final로 선언되면 내부 필드도 변경이 안될까?

2025. 4. 16. 12:17·개발 일기

💡 개요

 

클래스가 final로 선언되면 내부에 있는 필드 변수도 변경이 안될까?

 

 

 

🛠️ 클래스 필드가 final일 경우

 

public class ClassFinalTest {
    public static void main(String[] args) {
        Node node = new Node(1, 2);
        node.a++;
        node.b++;
    }

    static class Node {
        final int a;
        final int b;
        public Node(int a, int b) {
            this.a = a;
            this.b = b;
        }
    }
}

 

위 코드에선 Node의 int a와 int b가 final로 선언되어 있다.

 

 

 

그렇기 때문에 main() 메서드의 a와 b 값을 변경시키는 부분에서 컴파일 에러가 발생한다.

 

 

오케, 필드의 final은 변경이 불가능한 거 확인.

 

 

 

🛠️ 클래스 자체가 final인 경우

 

public class ClassFinalTest {
    public static void main(String[] args) {
        Node node = new Node(1, 2);
        node.a++;
        node.b++;
        System.out.println(node.a);
        System.out.println(node.b);
    }

    static final class Node {
        int a;
        int b;
        public Node(int a, int b) {
            this.a = a;
            this.b = b;
        }
    }
}

 

[결과]
2
3

 

 

이번엔 Node 클래스 자체를 final로 설정하였다.

 

 

결과는 a와 b값이 잘 변경된다.

 

 

컴파일 에러도 발생하지 않는다.

 

 

필드 내부에 final을 붙이면 값 변경이 안되지만, 클래스 자체에 final을 붙이면 내부 필드의 값이 변경 가능한 이유는 뭘까?

 

 

이유는 목적이 다르기 때문이다.

 

 

우리가 final을 사용하는 이유는 주로 불변이라는 특징을 사용해 안정성을 부여하기 위해서 이다.

 

 

하지만 이는 필드에 적용된 final에만 해당된다.

 

 

클래스 레벨의 final은 불변이 아니라 상속을 불가능하게 하기 위해서 사용한다.

 

 

클래스 내부의 인스턴스 필드가 변경 가능한지 여부와는 전혀 관련 없다.

 

public class ClassFinalTest {
    public static void main(String[] args) {
        Node node = new Node(1, 2);
        node.a++;
        node.b++;
        System.out.println(node.a);
        System.out.println(node.b);
    }

    static final class Node {
        int a;
        int b;
        public Node(int a, int b) {
            this.a = a;
            this.b = b;
        }
    }

    static class NodeChild extends Node {
        int c;
        public NodeChild(int a, int b, int c) {
            super(a, b);
            this.c = c;
        }
    }
}

 

위 코드를 보면 NodeChild는 Node를 상속받는다.

 

 

그런데 Node는 final로 선언되어 있기 때문에 NodeChild 부분에서 컴파일 에러가 발생한다.

 

 

발생되는 로그는 다음과 같다.

 

 

Cannot inherit from final 'classfinal_0416.ClassFinalTest.Node’

 

 

로그를 해석해보면 "Node 클래스는 final이기 때문에 상속이 불가능하다”라는 의미 같다.

 

 

명심하자 형석아.

 

  • 필드의 final → 불변
  • 클래스의 final → 상속 불가능

'개발 일기' 카테고리의 다른 글

[개발 일기] 2025.04.18 - DB 복합키  (0) 2025.04.18
[개발 일기] 2025.04.17 - Cookie 요소  (0) 2025.04.17
[개발 일기] 2025.04.15 - 자바 vector  (1) 2025.04.15
[개발 일기] 2025.04.14 - 스레드 로컬 (Thread Local)  (0) 2025.04.14
[개발 일기] 2025.04.13 - CQRS  (0) 2025.04.13
'개발 일기' 카테고리의 다른 글
  • [개발 일기] 2025.04.18 - DB 복합키
  • [개발 일기] 2025.04.17 - Cookie 요소
  • [개발 일기] 2025.04.15 - 자바 vector
  • [개발 일기] 2025.04.14 - 스레드 로컬 (Thread Local)
오도형석
오도형석
  • 오도형석
    형석이의 성장일기
    오도형석
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • MSA 모니터링 서비스
        • DB
      • 스파르타 코딩클럽
        • SQL
        • Spring
      • 백엔드
        • Internet
        • Java
        • DB
      • 캡스톤
        • Django
        • 자연어처리
      • Spring
        • JPA
        • MSA
      • ETC
        • ERROR
      • 개발 일기 N
  • 블로그 메뉴

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

  • 인기 글

  • 태그

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
오도형석
[개발 일기] 2025.04.16 - 클래스가 final로 선언되면 내부 필드도 변경이 안될까?
상단으로

티스토리툴바