왜 Kotlin에서 Java 정적 필드를 대체하기 위해“companion object”를 사용합니까?


145

"companion object"의 의도 된 의미는 무엇입니까? 지금까지 Java를 static필요할 때 교체하기 위해 사용 했습니다.

나는 혼란스러워한다.

  • 왜 "동반자"라고 불리는가?
  • 여러 정적 속성 을 만들려면 companion object블록 내에서 그룹화해야 합니까?
  • 클래스 범위의 싱글 톤 인스턴스를 즉시 생성하기 위해 종종

:

companion object {
    val singleton by lazy { ... }
}

일을하는 방법처럼 보입니다. 더 좋은 방법은 무엇입니까?

답변:


108
  • "companion object"의 의도 된 의미는 무엇입니까? 왜 "동반자"라고 불리는가?

    첫째, 코 틀린이의 자바 개념을 사용하지 않는 static코 틀린는 자신이 있기 때문에 구성원 의 개념 object 싱글의 상태와 연결 속성과 기능을 설명하기 위해, 자바 static클래스의 부분 우아한 싱글로 표현 될 수있다 : 그것은 싱글 톤 객체 그건 클래스 이름으로 호출 할 수 있습니다. 따라서 명명 : 그것은 클래스와 함께 제공되는 객체입니다.

    그 이름은로 사용 class object하고default object , 그러나 그것은에 이름이있어companion object 더 명확하고도 일치되는 스칼라 동반자 객체 .

    이름 지정 외에도 Java static멤버 보다 강력합니다 . 클래스와 인터페이스를 확장 할 수 있으며 다른 객체와 마찬가지로 참조 및 전달할 수 있습니다.

  • 여러 정적 속성을 만들려면 companion object블록 내에서 그룹화해야 합니까?

    예, 그것은 관용적 인 방법입니다. 또는 그 의미로 비 동반 객체로 그룹화 할 수도 있습니다.

    class MyClass {
        object IO {
            fun makeSomethingWithIO() { /* ... */ }
        }
    
        object Factory {
            fun createSomething() { /* ... */ }
        }
    }
  • 클래스 범위의 싱글 톤 인스턴스를 즉시 만들기 위해 나는 종종 /*...*/일을하는 일과 같은 것처럼 보입니다. 더 좋은 방법은 무엇입니까?

    그것은 각각의 특정한 경우에 필요한 것에 달려 있습니다. 코드는 클래스를 처음 호출 할 때 초기화되는 상태에 저장하는 데 적합합니다.

    클래스와 연결할 필요가 없다면 객체 선언을 사용하십시오.

    object Foo {
        val something by lazy { ... }
    }

    Java 정적 초기화 프로그램과 마찬가지로 lazy { ... }위임 을 제거 하여 첫 번째 클래스 사용시 특성을 초기화 할 수도 있습니다.

    싱글 톤 상태초기화하는 유용한 방법을 찾을 수도 있습니다 .


좋고 관용적 인 예.
Trein

19

왜 "동반자"라고 불리는가?

이 객체는 인스턴스의 동반자입니다. IIRC는 여기에 긴 토론이있었습니다 : 다가오는 변화-클래스-객체-재고

정적 속성을 여러 개 만들려면 컴패니언 객체 블록 안에 그룹화해야합니까?

예. 모든 "정적"속성 / 방법은이 컴패니언 내에 배치해야합니다.

클래스 범위의 싱글 톤 인스턴스를 즉시 생성하기 위해 종종

싱글 톤 인스턴스는 즉시 생성하지 않습니다. singleton처음 액세스 할 때 생성됩니다 .

일을하는 방법처럼 보입니다. 더 좋은 방법은 무엇입니까?

대신 object Singleton { }싱글 톤 클래스를 정의하십시오. 참조 : 개체 선언을 당신의 인스턴스를 만들 필요가 없습니다 Singleton, 그냥처럼 사용Singleton.doWork()

Kotlin은 코드를 구성 할 수있는 다른 기능을 제공합니다. 이제 간단한 정적 함수에 대한 대안이 있습니다. 예를 들어 최상위 기능을 대신 사용할 수 있습니다.


7

왜 "동반자"라고 불리는가?

클래스 내부의 객체 선언은 companion 키워드로 표시 할 수 있습니다.

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

클래스 이름을 한정자로 간단히 사용하여 컴패니언 객체의 멤버를 호출 할 수 있습니다.

val instance = MyClass.create()

'companion'없이 'object'만 사용하는 경우 다음과 같이해야합니다.

val instance = MyClass.Factory.create()

내 이해에서 '동반자'는이 객체가 외부 클래스와 동반된다는 것을 의미합니다.


"companion"이없는 "object"는 다음과 같이 호출됩니다 (MyClass (). create ()). 싱글 톤처럼 싱글 톤 객체에 접근하려면 먼저 "외부"클래스를 초기화해야합니다.
LiTTle

0

컴패니언은 Java와 같은 "Static Block"과 동일하다고 말할 수 있지만 Kotlin의 경우 컴패니언이 프레임에 들어오는 것보다 정적 블록 개념이 없습니다.

컴패니언 블록을 정의하는 방법 :

class Example {
      companion object {
        fun display(){
        //place your code
     }
  }
}

클래스 이름으로 직접 동반자 블록의 호출 방법

Example.Companion.display
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.