[이펙티브 자바] 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라

노을·2023년 2월 8일
0

이펙티브 자바

목록 보기
12/14
post-thumbnail

⭐ public 클래스에서 필드를 public으로 노출하지 말자!

class Point {
    public double x;
    public double y;
}

위 예제 처럼 필드를 public으로 노출하면 어떤 문제가 있을까?

☑️ 클라이언트 코드가 필드를 직접 사용하게 된다.

  • 필드 이름을 바꾼다면, 클라이언트 코드를 다 고쳐야 한다.
    Point point = new Point(1, 1);
    point.x = 2;
Point 객체를 만들고, x 값을 변경하려는 코드가 있다고 하자.
이때 x를 xCoordinate라는 필드명으로 바꾼다면 위 코드도 수정해야 한다.
    private int updateX(int x) {
        this.xCoordinate_ = x;
    }

    public static void main(String[] args) {
        Point point = new Point(1, 1);
        point.updateX(2);
    }

메서드로 필드에 접근하게 하면 필드 이름을 바꿔도 문제가 없다. (내부 표현에 묶이지 않는다.)

  • 필드 접근할 때 부수작업 불가
    접근자 메서드를 제공하면 부수작업이 가능해진다.
    public double getX() {
        // 부가 작업
        return x;
    }



⭐ package-private/private 클래스에서는 필드 노출을 해도 상관없다?

클라이언트 코드가 이 클래스 내부 표현에 묶이기는 하나, 클라이언트도 어차피 이 클래스를 포함하는 패키지 안에서만 동작하는 코드일 뿐이다.

이 글이 책에 써있는데
(개인적으로) 굳이 private이 아닌 public 필드로 해야 하나라는 생각이 든다.



⭐ 불변 필드를 노출한 public 클래스, 과연 좋을까?

불변를 노출하는 건 가변 필드 노출보다 덜 위험하지만, 내부표현에 묶이고, 부수작업을 수행할 수 없으므로 public 말고 private을 사용하자.



⭐ 내부를 노출한 Dimension 클래스의 성능 문제

Button button = new Button("hello button");
button.setBounds(0, 0, 20, 10);

Dimension size = button.getSize();
System.out.println(size.height); // height에 직접 접근
System.out.println(size.width);

button 객체의 getSize()Dimension 객체를 반환하고, 이 객체로 button의 사이즈를 알 수 있다. 하지만 height, widthpublic이라 직접 접근 가능하다.

public 필드이기 때문에,
객체를 안전하게 사용하기 위해서는
객체 자체가 아닌 객체를 복사한 다른 객체가 사용되게 만들어야 한다.

그러면 외부에서 객체를 사용할 때는 항상 새로운 객체를 만들어줘야 하는데, 이는 불편하고 객체 생성 비용이 크다면 성능에도 좋지 않다.

0개의 댓글