object 키워드를 통해 클래스를 정의하는 동시에 객체를 생성한다.
싱글턴을 정의하는 방법 중 하나이다.
companion object는 인스턴스 메소드는 아니지만 어떤 클래스와 관련 있는 메소드와 팩토리 메소드를 담을 때 쓰인다. compainon object 메소드에 접근할 때는 companion object가 포함된 클래스의 이름을 사용할 수 있다.
객체 식은 자바의 anonymous inner class 대신 쓰인다.
lazy하게 초기화 된다.
Kotlin은 object declaration 기능을 통해 싱글턴을 언어에서 기본 지원한다.
object declaration = 클래스 선언 + 그 클래스에 속한 단일 인스턴스의 선언
object declaration에 생성자 정의는 필요 없다. object declaration이 있는 위치에서 생성자 호출 없이 즉시 만들어지기 때문이다.
object declaration도 클래스나 인터페이스를 상속할 수 있다.
object Payroll {
val allEmployees = arrayListOf<Person>()
fun calculateSalary() {...}
}
Payroll.allEmployees.add(Person(...))
Payroll.calculateSalary()
data class Person(val name: String) {
object NameComparator : Comparator<Person> {
override fun compare(p1: Person, p2: Person): Int =
p1.name.compareTo(p2.name)
}
}
>>> val persons = listOf(Person("Bob"), Person("Alice"))
>>> println(persons.sortedWith(Person.NameComparator))
어떤 클래스의 모든 인스턴스가 공유하는 객체를 만들고 싶을 때 사용하며, 클래스당 한 개만 가질 수 있다.
자신을 둘러싼 클래스의 모든 private
멤버에 접근할 수 있다.
companion object의 프로퍼티나 메소드에 접근하려면 그 companion object가 정의된 클래스 이름을 사용한다.
이름을 생략할 수 있고 생략하게 되면 Companion이란 이름으로 접근할 수 있다.
class Obj {
companion object{
fun hi() = println("HI")
}
}
>>> Obj.hi()
>>> Obj.Companion.hi()
HI
HI
// Obj.멤버는 Obj.Companion.멤버의 축약표현!!!!
class Person(val name: String) {
companion object Loader {
fun fromJSON(jsonText: String) : Person { ... }
}
}
>>> person = Person.Loader.fromJSON("{name: 'Dmitry'}")
>>> person.name
Dmitry
>>> person = Person.fromJSON("{name: 'Brent'}")
>>> person.name
Brent
팩토리 패턴
을 구현하기 가장 적합한 위치이다.class User private constructor(val nickname: String) {
companion object {
fun newSubscribingUser(email: String) = User(email.substringBefore('@'))
fun newFacebookUser(accountId: Int) = User(getFacebookName(accountId))
}
}
interface JSONFactory<T> {
fun fromJSON(jsonText: String): T
}
class Person(val name: String) {
companion object : JSONFactory<Person> {
override fun fromJSON(jsonText: String): Person {...}
}
}
class Obj {
companion object{
fun hi() = println("HI")
}
}
>>> val obj = Obj.Companion
>>> obj.hi()
HI
>>> val obj2 = Obj
>>> obj2.hi()
HI
@JvmStatic
애노테이션을 코틀린 멤버에 붙이면 된다. static field가 필요하면 @JvmField
애노테이션을 붙인다.