아이템 16 - public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 - 핵심 정리
이 글은 백기선 님의 이펙티브 자바 강의와 이펙티브 자바 3 / E 편을 참고하여 작성하였습니다.
public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라.
주의할 점은 public 클래스인 경우에 해당한다는 것이다.
public class Point {
public double x;
public double y;
}
위와 같이 public 필드를 사용하면 외부 클래스에서는
public class main {
public static void main(String[] args) {
Point point = new Point();
point.x = 10;
point.y = 20;
System.out.println(point.x);
System.out.println(point.y);
}
}
직접 필드에 접근하여 값을 사용하게 된다.
이렇게되면 캡슐화의 장점 을 제공하지 못한다.
만약 필드명을 변경하게 된다면 Point 클래스를 사용하는 모든 코드들이 변경되어야 한다.
그리고 필드에 값을 할당할 때 제약 을 줄 수가 없다.
값을 가져갈 때 역시 부가적인 작업을 할 수 없다.
// 코드 16-2 접근자와 변경자(mutator) 메서드를 활용해 데이터를 캡슐화한다. (102쪽)
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
// 부가 작업
return x;
}
public double getY() { return y; }
public void setX(double x) {
// 부가 작업
this.x = x;
}
public void setY(double y) { this.y = y; }
}
위와 같이 모든 필드를 private 으로 바꾸고 getter
, setter
메서드를 제공해준다.
이렇게하면 필드이름을 바꾸더라도 메서드 이름이 유지되기 때문에 유연하게 변경할 수 있다.
메서드 접근이기 때문에 부가적인 작업이 가능해진다.
만약 클래스가 package-private
인 경우에는 굳이 필드들을 private
으로 만들 필요가 없다.
그렇다하더라도 필드에 직접 접근보다는 public 한 메서드를 통해 필드에 접근하는 것이 이점이 더 많다.
// 코드 16-3 불변 필드를 노출한 public 클래스 - 과연 좋은가? (103-104쪽)
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: " + hour);
if (minute < 0 || minute >= MINUTES_PER_HOUR)
throw new IllegalArgumentException("Min: " + minute);
this.hour = hour;
this.minute = minute;
}
// 나머지 코드 생략
}
final 키워드 를 사용한 불변으로 만든 필드를 노출하면 그나마 단점이 조금 줄어든다.
public 필드를 노출 하게되면 어디서 어떻게 값이 변경될지 알 수 없다.
떄문에 안전하게 사용하기 위해서는 해당 객체를 사용하는 쪽에서 값을 해당 scope 내에서 복사 해서 사용한다.
다른 메서드나 다른 객체에 넘겨주는 경우에 복사 를 사용한다.
public class main {
public static void main(String[] args) {
Point point = new Point();
point.x = 10;
point.y = 20;
doSomething(point); // 값이 어떻게 변할지 알 수 없다.
System.out.println(point.x);
System.out.println(point.y);
}
}
메서드 호출 후에 값이 어떻게 변경이 되었을지 알 수 없게된다.
public class main {
public static void main(String[] args) {
Point point = new Point();
point.x = 10;
point.y = 20;
doSomething(point); // 값이 어떻게 변할지 알 수 없다.
System.out.println(point.x);
System.out.println(point.y);
}
private static void doSomething(Point point) {
Point localPoint = new Point();
localPoint.x = point.x;
localPoint.y = point.y;
}
}
안전하게 사용하기 위해서는 객체를 복사 하여 사용해야한다.
사실상 한번 public 으로 공개한 클래스는 어디서 사용하는지 알 수 없기 때문에 컨트롤하기가 불가능하다.
때문에 getter
, setter
메서드를 제공해 필드에 접근할 수 있도록 해야한다.
'개발 공부 > Java' 카테고리의 다른 글
이펙티브 자바 아이템 17 - 변경 가능성을 최소화 하라 - 핵심 정리 (0) | 2022.11.21 |
---|---|
이펙티브 자바 아이템 16 - public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라 - 완벽 공략 (1) | 2022.11.14 |
이펙티브 자바 아이템 15 - 클래스와 멤버의 접근 권한을 최소화하라 - 완벽 공략 (0) | 2022.11.09 |
이펙티브 자바 아이템 15 - 클래스와 멤버의 접근 권한을 최소화하라 - 핵심 정리 (0) | 2022.11.08 |
이펙티브 자바 아이템 14 - Comparable 을 구현할지 고민하라 - 완벽 공략 (0) | 2022.10.31 |
댓글