프로그래밍백엔드 개발자

Kotlin에서 최상위 함수 및 속성에 대한 가시성 수정자(internal/private/protected/public) 메커니즘은 어떻게 작동합니까? Java와의 차이점 및 고려해야 할 뉘앙스는 무엇입니까?

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

답변.

Kotlin에서 가시성 수정자는 클래스, 속성, 함수 및 최상위(파일 수준) 선언에 대한 접근을 제어하는 데 사용됩니다. Java와 달리 수정자가 클래스 수준에서만 작동하는 대신, Kotlin에서는 최상위 선언에도 적용되어 대규모 프로젝트와 라이브러리 API를 구조화하는 데 중요합니다.

질문의 배경

Java에는 클래스 외부의 함수나 속성에 대한 가시성 수정자가 없습니다 — 모든 것이 public(또는 package-private) 클래스 내부에 있습니다. Kotlin에서는 프로젝트를 구조화하는 방식이 달라지며, 종종 함수나 속성이 클래스 안이 아닌 파일 자체에 존재합니다.

문제

Java 개발자는 종종 기본적으로 public이 Java와 같은 방식으로 작동할 것이라고 예상하지만, Kotlin의 경우 최상위 함수(또는 속성)는 다르게 표시되지 않는 한 모든 모듈에서 볼 수 있습니다. 잘못된 가시성 정의는 공개 API의 어휘적 오염을 초래하거나, 내부 유틸리티의 예기치 않은 가시성을 제공하거나, 필요한 공개 함수가 사용 불가능해질 수 있습니다.

해결책

Kotlin에서는 다음과 같은 수정자를 사용할 수 있습니다:

  • public: 선언이 어디서나 보입니다 (최상위의 기본 수정자).
  • internal: 선언이 동일 모듈의 모든 파일에서 보입니다 (하나의 gradle 모듈, 하나의 컴파일 아티팩트, 하나의 jar).
  • private: 선언된 파일/클래스 내에서만 보입니다. 최상위에서는 파일 내에서만 가능합니다.
  • protected: 최상위 선언에 적용할 수 없으며, 클래스/인터페이스 및 그 상속 클래스에서만 적용됩니다.

예:

// file: Foo.kt private fun utilityFun() {} internal val bar: Int = 10 public val baz: Int = 20 // public은 선택적 fun printValue() { println(bar) }

주요 특징:

  • internal은 모듈(jar/artifact)에 따라 가시성을 제한하며, 패키지에 따라 제한하지 않습니다.
  • protected는 최상위 함수나 속성에 사용할 수 없습니다.
  • 최상위의 private는 현재 파일 내에서 선언을 제한합니다.

문제성 질문.

최상위 함수에 protected를 사용할 수 있습니까?

아니요, protected는 클래스/인터페이스의 멤버에게만 해당되며, 최상위 요소는 지원하지 않습니다.

최상위 함수를 internal로 선언하면 다른 모듈 내에서 보일까요?

아니요. 해당 함수는 현재 jar/Gradle 모듈 내에서만 보입니다.

private class와 private top-level function의 차이는 무엇입니까?

  • private class: 현재 파일 내에서만 보이며, 파일 외부에서는 사용할 수 없습니다.
  • private top-level function 또는 속성: 마찬가지로 파일 내에서만 보입니다.

예:

// file: Utils.kt private fun helper() { /* ... */ } // 이 파일 내에서만 보임 internal fun useful() { /* ... */ } // 모듈 내에서 보임

일반적인 오류 및 안티 패턴

  • 모든 선언에 대해 public 기본값을 사용하는 것은 자동 완성과 API의 "오염"으로 이어집니다.
  • 외부 클라이언트를 위한 라이브러리에 internal을 사용하면 필요한 public API가 숨겨집니다.
  • protected와 혼란스러워하고 이를 최상위에 적용하려는 시도.

실생활 사례

부정적 사례

테스트 유틸리티가 public으로 선언되어 artefact에 포함되어 라이브러리 클라이언트에 방해가 됩니다 — public API와 관련 없는 모든 것이 보이게 됩니다.

장점:

  • 빠른 통합.

단점:

  • 공개 API의 크기가 커지고 "우연한" 메서드가 접근 가능해집니다.

긍정적 사례

내부 함수는 private로 선언되고, 공용 사용을 위해 internal 가시성의 유틸리티만 있으며, 신중하게 설계된 인터페이스만이 public 접근을 가집니다.

장점:

  • 명확하고 깔끔한 API 구조.
  • 우연한 종속성을 최소화합니다.

단점:

  • 프로젝트 구조를 신중히 고려해야 합니다.