Java/강의

[📙 Java 문법 종합반] 2-5. final - 변하지 않는 값

가지코딩 2025. 4. 15. 17:34

📙 목차

  1. final
  2. 상수(Constant)
  3. 불변객체(Immutable Object)

🧡 학습 목표

  • final 키워드에 대해서 학습한다.
  • 상수(Constant)와 불변객체(immutable object)가 무엇인지 학습한다.

1. final

final 키워드

  • 변수는 변경이 불가능하게 만든다.
  • 클래스는 상속할 수 없게 만든다.
  • 메서드는 수정할 수 없게 만든다.(오버라이딩 불가)
final int a = 100;
a = 200; // ❌ 오류 발생!
final class Animal {
    void sound() {
        System.out.println("Animal sound!");
    }
}

// class Dog extends Animal {} // ❌ 오류! final 클래스는 상속할 수 없음
class Parent {
    final void show() {
        System.out.println("Hello from Parent");
    }
}

class Child extends Parent {
    @Override
    void show() { // ❌ 오류! final 메서드를 재정의할 수 없음
        System.out.println("Hello from Child");
    }
}

2. 상수(Constant)

상수(constant)

  • 상수는 변하지 않고 항상 일정한 값을 갖는 수이다.
  • Java에서 상수는 대문자로 표현하는 것이 관례이다.
  • 프로그램 실행중에 절대 변경되서는 안되기 때문에 static final 키워드를 사용해 선언한다.
  • static 으로 선언된 변수는 프로그램 시작시 한 번만 초기화되고 모든 인스턴스에서 같은 값을 공유한다.

 

대표적인 상수 예시: PI(원주율)

public class Circle {
    final static double PI = 3.14159; // ✅ 상수 선언
}
System.out.println("상수활용: " + Circle.PI);

 

 

* static 으로 선언하는 이유

  • 보통 상수는 여러 곳에서 값을 공유해 쓰일 목적으로 활용된다.
  • 인스턴스 변수를 static 없이 선언할 경우 인스턴스마다 PI 값이 중복 저장된다.

3. 불변객체(Immutable Object)

불변객체(Immutable Object)

  • 불변객체는 내부 상태를 변경할 수 없는 객체이다.
  • 모든 속성(property, field)은 final로 선언한다.
  • 세터(setter) 없이 설계한다.
  • 변경이 필요할 경우 새로운 객체를 만들어야 한다.
  • ex) String , Integer , 래퍼클래스 등
public final class Circle { // final 선언 (상속 방지)
	
    // ✅ final 로 선언해서 값이 변경되지 않도록 한다.
    final static double PI = 3.14159; 
    final double radius; 

    Circle(double radius)  {
        this.radius = radius;
    }
}

 

 

클래스 캡슐화를 배우고 난 후 활용할 수 있는 모범사례(참고용)

더보기
더보기
public final class Circle { // ✅ 클래스에 final 선언 (상속 방지)
    
    private static final double PI = 3.14159; // ✅ 상수는 private static final로 선언
    private final double radius; // ✅ 필드를 private final로 선언하여 완전한 불변성 유지

    public Circle(double radius) { // ✅ 생성자는 public으로 유지
        this.radius = radius;
    }

    public double getRadius() { // ✅ public 메서드로 변경
        return radius;
    }

    public double getArea() { // ✅ public 메서드로 변경
        return PI * radius * radius;
    }

    public double getPerimeter() { // ✅ public 메서드로 변경
        return 2 * PI * radius;
    }
}

 

 

* 불변 객체의 값 변경이 필요한 경우

  • 불변성을 유지하면서 값을 변경하는 효과를 얻을 때 활용한다.
  • 기존 객체의 상태를 직접 변경할 수 없기 때문에 새로운 객체를 생성한다.
  • 생성자를 새로 호출하거나 아래의 기능을 활용할 수 있다.
public final class Circle {
    public static final double PI = 3.14159;
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    // ✅ 반지름이 다른 새로운 Circle 생성 (불변 객체 유지)
    public Circle changeRadius(double newRadius) {
        return new Circle(newRadius); // 생성자 호출: 기존 객체 변경 X, 새 객체 생성
    }
}