8. Object & Singleton

object 키워드와 싱글톤

치트시트

  • object 선언: 싱글톤(잘 안씀)

  • companion object: 클래스와 동행하는 유일한 객체, Java static 대체

  • @JvmStatic: 자바에서 정적 접근 지원

  • object : Type: 익명 객체 생성

  • 권장: 단순 유틸 → 최상위 함수, 상태 공유/전략 객체 → object 싱글톤


1) static vs companion object

  • Java: 클래스 내부에 static 변수/메소드 선언

  • Kotlin: static 키워드 없음 → companion object 사용

class Utils {
    companion object {
        fun now() = System.currentTimeMillis()
    }
}
  • companion object는 클래스와 함께 존재하는 유일한 객체

  • 이름을 붙일 수 있고, 인터페이스를 구현하거나 상속 가능

  • Java에서 호출 시: Utils.Companion.now()

  • @JvmStatic 붙이면 Utils.now()로 바로 호출 가능

👉 단순 유틸 함수라면 클래스 안보다 파일 최상단 함수가 더 권장됨


2) object 선언 (싱글톤)

  • 코틀린은 싱글톤을 언어 차원에서 지원

  • object로 클래스를 선언하면 자동으로 싱글톤 인스턴스 생성

object Logger {
    fun log(msg: String) = println("[LOG] $msg")
}

Logger.log("Hello")
  • 멀티스레드 환경에서도 안전하게 초기화됨

  • 자바에서 enum 기반 싱글톤을 만드는 보일러플레이트가 불필요


3) 익명 객체 (Anonymous object)

  • Java: new 인터페이스() { ... }

  • Kotlin: object : 타입 { ... }

val listener = object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent?) {
        println("clicked")
    }
}

👉 UI 이벤트 리스너, 테스트 Mock 등에 자주 활용.


4) 실무 활용 패턴

A. 싱글톤 Repository

object UserRepository {
    private val users = mutableListOf<String>()

    fun add(u: String) = users.add(u)
    fun getAll(): List<String> = users
}

→ Spring Bean처럼 DI 컨테이너가 없더라도 간단하게 싱글톤 관리 가능.

B. Companion + Factory

class User private constructor(val id: Int) {
    companion object {
        fun create(id: Int) = User(id)
    }
}

→ 생성자 은닉 + 팩토리 메소드 제공.

C. 인터페이스 구현

interface JsonMapper { fun toJson(): String }

object DefaultMapper : JsonMapper {
    override fun toJson() = "{}"
}

→ object도 타입 구현체가 될 수 있어, 전략 객체를 싱글톤으로 제공 가능.

Last updated