Java

[Effective Java] 아이템16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라

jun9.com 2022. 4. 15. 23:23

1.  멤버는 private, 접근자는 public으로

public class Point {
    private double x;
    private double y; // 멤버는 모두 private

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {	return x;	} // getter는 public으로 멤버변수에 접근할 수 있게 한다.
    public double getY() {	return y;	}


    public void setX(double x) {   this.x = x;	}
    public void setY(double y) {	this.y = y;	}
}
  • public 클래스라면 외부에서 멤버변수에 접근할 수 있어야 한다.
  • 멤버 자체를 public으로 둔다면
    • 내부 표현을 바꾸기 위해 API를 수정해야 하고
    • 외부에서 멤버에 접근할 때 접근만 가능 할 뿐 부가 작업을 수행할 수 없다.
  • 따라서 멤버는 private, getter/setter메서드는 public으로 두는게 public class 목적에 맞다.

※ pakcage-private 클래스이거나 클래스 내 private으로 클래스가 중첩된다면!!

  • 데이터 필드를 노출해도 된다.
    • 클래스가 표현하려는 추상 개념만 올바르게 표현해주면 문제가 없다.
  • 패키지 바깥 코드는 손대지 않고 데이터 표현 방식을 바꿀 수 있다. private 중첩 클래스라면 수정 범위가 더 좁아진다!

 

2. 불변 필드를 노출한 public 클래스

public final class Time {
    private static final int HOURS_PER_DAY = 24;
    private static final int MINUTES_PER_HOUR = 60;

    public final int hour;
    public final int minute;

    public Time(int hour, int minute) {
       if(hour < 0 || hour >= HOURS_PER_DAY) // 시간 유효성 검증
        	throw new IllegalArgumentException("시간: "+ hour);
        if(minute < 0 || minute >=  MINUTES_PER_HOUR) // 분 유효성 검증
        	throw new IllegalArgumentException("분: "+ minute);
            
        this.hour = hour;
        this.minute = minute;
    }

    ...
}
  • 단점
    • 표현방식을 바꾸려면 API도 변경해야 한다.
    • 필드를 읽을 때 부수작업을 수행할 수 없다.
  • 장점
    • 불변식을 보장할 수 있다.

 

정리) public 클래스라면 가변 필드를 직접 노출해서는 안된다.

불변 필드라면 노출해도 덜 위험하지만, 필드 수정/제거에 제약이 있다.