7. Visibility & Access Modifiers

접근 제어자와 가시성

치트시트

  • 기본값: Java → default(package), Kotlin → public

  • protected: Java → 패키지+상속, Kotlin → 상속만

  • internal: 모듈 범위, 바이트코드 상 public

  • 파일 단위: private, internal 사용 가능

  • 생성자 제한: private constructor + companion factory

  • 프로퍼티: getter/setter 별도로 가시성 부여 가능


1) 기본 접근 제어자 비교 (Java vs Kotlin)

접근 제어자
Java
Kotlin

public

모든 곳에서 접근 가능

동일

protected

같은 패키지 + 하위 클래스

선언된 클래스 + 하위 클래스 (패키지 X)

(default)

같은 패키지에서만 접근 가능

없음 (Kotlin은 기본값이 public)

private

같은 클래스 내

동일

internal

없음

같은 모듈 내에서만 접근 가능

👉 중요 차이

  • Kotlin의 기본값은 public

  • internal은 Gradle 모듈, Maven 프로젝트, Source Set 단위

  • protected는 패키지 단위가 아니라 상속 구조 기반


2) 파일 단위 접근 제어

  • Kotlin은 .kt 파일에 여러 클래스/함수/변수를 정의할 수 있음

  • 파일 최상단 요소도 접근 제어 가능

// Utils.kt
internal fun now() = System.currentTimeMillis()
private val secret = "hidden"
  • internal: 같은 모듈 안에서만 사용 가능

  • private: 같은 파일 내에서만 접근 가능


3) 클래스, 생성자, 프로퍼티

  • 클래스 멤버의 접근 제어: public, protected, internal, private

  • 생성자도 동일하지만, 가시성을 붙일 때는 constructor 필요

class User private constructor(val id: Int) {
    companion object {
        fun create(id: Int) = User(id)
    }
}
  • 프로퍼티는 getter/setter에 서로 다른 접근 제어 부여 가능

var password: String = "1234"
    private set   // 외부에서 읽을 수는 있지만, 수정은 불가

4) Java와 Kotlin 함께 사용할 때 주의점

  • internal은 바이트코드 상 public으로 컴파일 → Java 코드에서 접근 가능

  • protected: Java에서는 같은 패키지 내에서 접근 가능하지만, Kotlin protected는 상속 관계에서만 허용


5) 실무 활용 패턴

A. 모듈 경계 명확화

  • Kotlin 멀티모듈 프로젝트: internal로 모듈 내부 구현 숨기기

  • 외부에 노출할 API만 public

B. DTO/Entity 제어

data class User internal constructor(
    val id: Long,
    val email: String
)

→ 외부 모듈에서 객체 직접 생성 막고, 팩토리/레포지토리 통해 생성.

C. 프로퍼티 Setter 제한

class Account {
    var balance: Int = 0
        private set
}

→ balance는 외부에서 읽기만 가능, 변경은 내부 로직에서만.

Last updated