프로그래밍자바 개발자

자바에서 클래스 멤버에 대한 접근 제어는 어떻게 작동하며 다양한 접근 제어 수Modifier 사용 시 어떤 함정이 있는가?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사:

자바에서 데이터와 메서드에 대한 접근 수준을 제어하는 것은 캡슐화와 클래스의 내부 구조 보호를 위해 도입되었습니다. 이는 구현을 숨기고 객체의 상태가 무단으로 변경되는 것을 방지하는 객체 지향 프로그래밍의 중요한 부분입니다.

문제:

다양한 접근 제어 수Modifier — public, protected, (package-private), private — 는 클래스 멤버의 가시성을 다르게 제한합니다. 이는 종종 명확하지 않습니다. 잘못 선택된 수준은 버그, 원치 않는 권한 확대, 캡슐화 위반으로 이어질 수 있습니다.

해결책:

각 필드나 메서드에 최소한의 필요 접근 제어 수Modifier를 사용하십시오. 자바는 다음을 지원합니다:

  • private — 같은 클래스 내부에서만 접근 가능
  • (package-private) — 수Modifier가 지정되지 않으면 패키지 내에서만 접근 가능
  • protected — 패키지 내부 및 서브클래스에서 접근 가능 (패키지 외부에 있는 경우에도)
  • public — 어디서나 접근 가능

코드 예제:

public class Dog { private String name; // Dog 내부에서만 볼 수 있음 String breed; // package-private protected int age; // 패키지 및 상속받은 클래스에서 볼 수 있음 public void bark() { // 어떤 코드에서도 접근 가능 System.out.println("Woof!"); } }

핵심 특징:

  • 기본적으로 package-private가 선택됨
  • 자바의 protected는 C++와 다름 (자바는 패키지 내 가시성!)
  • private는 리플렉션을 통한 접근을 방지하지 않지만 이것에 의존하지 않는 것이 좋음

함정이 있는 질문.

내부 (inner) 클래스는 외부 클래스의 모든 private 필드에 접근할 수 있는가?

예, 내부 클래스는 외부 클래스의 모든 필드와 메서드에 완전히 접근할 수 있습니다, 심지어 private도 말이죠. 반대로 외부 클래스는 내부 클래스의 private 멤버를 해당 인스턴스를 통해 접근할 수 있습니다.

protected 멤버가 상속 없이 패키지 외부에서 접근 가능할 수 있는가?

아니요. 패키지 외부에서는 protected는 오직 상속된 경우에만 유용합니다. 다른 패키지에서 클래스 객체를 통해서는 접근할 수 없습니다.

클래스가 public으로 선언되지 않았으나 다른 패키지에서 임포트 되는 경우 어떤 일이 발생하는가?

package-private 수준의 클래스는 자신의 패키지 외부에서 명시적으로 임포트되고 사용될 수 없습니다. 다른 패키지의 코드에서 이를 접근하려고 하면 컴파일 오류가 발생합니다.

일반적인 오류 및 안티 패턴

  • 클래스의 필드를 public으로 열어 캡슐화를 위반
  • protected를 "안전한" 접근 수준으로 믿고 패키지 내 가시성을 고려하지 않음
  • package-private를 사용하면서 이를 패키지 내 모든 클래스에서 볼 수 있다는 것을 이해하지 못함

실생활 사례

부정적 사례

모든 DTO 클래스 필드가 public으로 표시되어 접근성을 단순화함

장점:

  • 빠름, getter/setter를 작성할 필요 없음

단점:

  • 캡슐화 위반, 데이터의 예기치 않은 수정 가능
  • 객체의 상태를 제어하기 어려움

긍정적 사례

private 필드와 공개 접근 메서드를 사용함

장점:

  • 객체의 내부 상태에 대한 제어 가능
  • 불변 조건 유지 및 디버깅이 용이함

단점:

  • 코드가 조금 더 많음 (getter/setter)