object는 Kotlin에서 기본적으로 지연 초기화와 스레드 안전성을 갖춘 싱글톤 객체를 생성하는 선언적 방법입니다. object 키워드는 단일 인스턴스로 전체 클래스를 대체하며 싱글톤, companion object, 익명 객체 및 정적 유틸리티를 선언하는 데 사용됩니다. JetBrains Kotlin Documentation(2026)에 따르면 object declaration은 JVM 세계에서 싱글톤을 구현하는 가장 간단하고 안전한 방법입니다.
주요 포인트
object는 Kotlin에서 클래스를 정의하는 동시에 해당 단일 인스턴스(싱글톤)를 생성하는 특별한 선언 형태입니다. 하나의 구성에서 클래스 선언과 인스턴스 생성의 하이브리드입니다.
Java에서 싱글톤을 만들려면 private 생성자, static 필드, getInstance 메서드 및 스레드 안전 처리가 필요합니다. Kotlin object는 한 줄의 코드로 이 작업을 수행합니다: object MySingleton { }. 컴파일러는 JVM 바이트코드의 static initializer 메커니즘을 사용하여 자동으로 스레드 안전한 지연 초기화를 생성합니다.
Kotlin 언어 사양(2026)에 따르면 object declaration은 private 생성자와 static 블록에서 초기화되는 static INSTANCE 필드를 가진 final 클래스로 컴파일됩니다. 이는 JVM 수준에서 초기화의 원자성을 보장합니다.
Object declaration(싱글톤 객체)은 object 키워드 다음에 이름을 사용하여 선언됩니다. 객체 본문에는 속성, 메서드, init 블록이 포함될 수 있으며 다른 클래스나 인터페이스를 상속할 수 있습니다.
object DatabaseManager {
private val connection: String = "jdbc:postgresql://localhost:5432/app"
fun query(sql: String): List<Map<String, Any>> {
// 쿼리 실행 중
return emptyList()
}
}
// 사용법
DatabaseManager.query("SELECT * FROM users")
DatabaseManager의 초기화는 첫 액세스 시 발생합니다 — 지연 및 스레드 안전하게. 추가 동기화 코드가 필요하지 않습니다.
Object는 일반 클래스와 인터페이스를 상속할 수 있습니다. 이를 통해 단일 인스턴스를 가진 추상 클래스나 인터페이스의 구현으로 object를 사용할 수 있습니다.
interface Logger {
fun log(message: String)
}
object ConsoleLogger : Logger {
override fun log(message: String) {
println("[LOG] $message")
}
}
companion object는 companion 키워드로 클래스 내부에 선언되는 특별한 object입니다. Kotlin에는 static 키워드가 없으므로 정적 멤버를 대체합니다.
class ApiClient {
companion object {
private const val BASE_URL = "https://api.example.com"
fun create(): ApiClient {
return ApiClient()
}
}
}
// ApiClient 인스턴스를 생성하지 않고 호출
val client = ApiClient.create()
Companion object는 이름을 가질 수 있고(기본값은 Companion), 인터페이스를 구현하며, extension functions을 통해 확장될 수 있습니다. Java의 정적 메서드와 달리 companion object는 인수로 전달되거나 변수에 저장될 수 있는 완전한 객체입니다.
Kotlin 모범 사례(2026)에 따르면 companion object는 팩토리 메서드, 상수 및 클래스와 관련된 정적 유틸리티에 사용됩니다. companion object의 과도한 사용은 피하는 것이 좋습니다 — 관련 없는 유틸리티에는 최상위 함수가 더 적합합니다.
Java 호환성을 위해 companion object의 메서드에 @JvmStatic을 지정할 수 있습니다. 이렇게 하면 JVM 바이트코드에서 실제 정적 메서드가 생성되어 Companion 구문 없이 Java 코드에서 액세스할 수 있습니다.
Object expression은 별도의 명명된 클래스를 선언하지 않고 클래스나 인터페이스의 메서드를 재정의하기 위해 즉석에서 생성되는 익명 객체입니다.
val handler = object : Runnable {
override fun run() {
println("작업이 실행되었습니다")
}
}
thread(handler)
Object expressions는 실행될 때마다 새 인스턴스를 생성한다는 점에서 object 선언과 다릅니다. 싱글톤이 아니며 이름이 없습니다. 익명 객체는 람다와 마찬가지로 클로저에서 변수를 캡처할 수 있습니다.
익명 클래스가 하나의 유형만 상속할 수 있는 Java와 달리 Kotlin의 object expression은 동시에 여러 유형을 상속할 수 있습니다.
interface Clickable {
fun click()
}
abstract class View {
abstract fun render()
}
val button = object : View(), Clickable {
override fun render() = println("버튼 렌더링 중")
override fun click() = println("버튼이 클릭되었습니다")
}
Object는 Kotlin에서 가장 다재다능한 구성 중 하나이며 많은 시나리오에서 사용됩니다.
Android 프로젝트에서 object는 여러 인스턴스가 필요하지 않은 Repository를 선언하는 데 자주 사용됩니다. 단일 인스턴스는 데이터 일관성을 보장합니다.
object UserRepository {
fun getUser(id: Int): User? {
// 사용자 가져오는 중
return null
}
}
Companion object와 팩토리 메서드는 여러 생성자의 대안입니다. 이름이 지정된 팩토리 메서드는 코드를 자체 문서화합니다.
data class GsonParser {
companion object {
fun create(): GsonParser = GsonParser()
fun createPretty(): GsonParser = GsonParser()
}
}
Object는 상수 컨테이너 역할을 하여 Java의 static final 필드를 대체합니다. Object는 상속을 지원하므로 구성 계층 구조를 만들 수 있습니다.
Kotlin 표준 라이브러리(2026)에 따르면 object declaration은 Kotlin에서 싱글톤을 만드는 가장 효율적인 방법이며 double-checked locking 구현을 능가하고 Java의 enum 싱글톤과 비슷합니다.
자주 묻는 질문
Object는 클래스를 선언하는 동시에 단일 인스턴스를 생성합니다. 일반 클래스는 생성자를 통해 생성된 여러 인스턴스를 가질 수 있습니다.
지연 — 객체에 처음 액세스할 때입니다. 그때까지는 메모리가 할당되지 않으며 init 블록의 코드가 실행되지 않습니다.
아니요, object는 명시적 생성자를 가질 수 없습니다. 초기화는 init 블록에서 수행되며 객체에 처음 액세스할 때 한 번 호출됩니다.
companion object는 클래스 내부에 선언된 object입니다. 해당 멤버는 인스턴스를 생성하지 않고 클래스 이름을 통해 액세스할 수 있으며 Java의 정적 멤버를 대체합니다.
예, object의 초기화는 JVM 정적 초기화 덕분에 완전히 thread-safe합니다. 추가 동기화가 필요하지 않습니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.