접근 지정자

  • private 같은 클래스만 허용
  • public 패키지에 상관없이 모든 클래스에서 허용
  • 접근 지정자 생략 (default) 같은 패키지만 허용
  • protected 같은 패키지 or 자식 클래스만 허용

무분별한 세터(setter) 사용

  1. private + setter 동시 사용
    • 결과) 의미 없음
    • 해결 방법) 세터 안에 조건문 사용해서 무분별한 세터 사용 방지
  2.  너무 세분화된 동작을 각각의 세터로 기능하도록 해서 메인 클래스에서 중복/혼잡한 세터 사용
    • 결과) 정신사나움
    • 해결 방법) 특정 범위 동작을 하나의 세터 안에 넣고 번에 실행하도록 묶어주기

 

final 

final 클래스 해당 클래스를 상속받을 수 없음

final class FinalClass {
    public void show() {
        System.out.println("This is a final class.");
    }
}

// 오류: final 클래스는 상속할 수 없음
class ChildClass extends FinalClass {
    public void show() {
        System.out.println("This is a child class.");
    }
}

 

final 메소드 오버라이딩 불가

class Parent {
    public final void display() {
        System.out.println("Parent display");
    }
}

class Child extends Parent {
    // 오류: final 메서드는 오버라이드할 수 없음
    public void display() {
        System.out.println("Child display");
    }
}

 

final 필드 해당 필드는 상수가 되어 변경 불가

final int x = 10; // x는 10으로 고정됨
x = 20; // 컴파일 에러: final 변수는 값을 변경할 수 없음

 

final 매개변수 해당 파라미터 값 변경 불가

public void calculate(final int x) {
    x = x + 5; // 오류: final 매개변수는 변경할 수 없음
}

 

불변객체 (Immutable Object)

  • 내부 상태를 변경할 수 없는 객체
  • final을 속성에 활용
  • setter 없이 설계
  • 변경이 필요할 경우, 새로운 객체 생성 필요

 

잘못된 불변객체 사용 사례

public class Circle {

    final static double PI = 3.14159; // ✅ 직접 만든 원주율 상수
    double radius; // ⚠️ final 로 선언되어 있지 않기 때문에 외부에서 변경 가능

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


final Circle c1 = new Circle(2);
c1 = new Circle(3); // ❌ 
// final은 변수 c1이 한 번 참조한 객체는 다른 객체로 변경될 수 없음을 의미함 (참조 불변)

c1.radius = 3; // ⚠️ 내부 상태 변경 가능 (객체 자체가 불변이 아님)

 

올바른 불변객체 사용 사례

public final class Circle {

    final static double PI = 3.14159; 
    final double radius; // ✅ final 로 선언해서 값이 변경되지 않도록

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

 

 

불변객체의 값이 변경이 필요할 경우

1. 새로운 객체 생성

2. 클래스의 함수 내에서 새로운 객체 생성 -> 메인 클래스에서 마치 값을 변경하는 것처럼 사용 가능

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, 새 객체 생성
    }
}

'언어, 프레임워크 > Java' 카테고리의 다른 글

JDK 패키지와 클래스  (1) 2025.02.04
상속 (super(), 캐스팅, 동적/정적 바인딩, 추상 클래스, 인터페이스)  (0) 2025.02.03
this() / 가비지 컬렉션  (1) 2025.02.03
예외 처리  (0) 2025.01.31
배열  (0) 2025.01.31