web-dev-qa-db-ja.com

KotlinのJava静的フィールドの一種として「コンパニオンオブジェクト」を使用するのはなぜですか?

「コンパニオンオブジェクト」の意図する意味は何ですか?これまでのところ、必要なときにJavaのstaticを置き換えるためだけに使用しています。

私は混乱しています:

  • なぜ「コンパニオン」と呼ばれるのですか?
  • 複数のstaticプロパティを作成するには、companion objectブロック内でグループ化する必要があるということですか?
  • クラスをスコープとするシングルトンインスタンスを即座に作成するには、次のように記述します。

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

それはそれを行うための単一の方法のように思えます。より良い方法は何ですか?

130
  • 「コンパニオンオブジェクト」の意図する意味は何ですか?なぜ「コンパニオン」と呼ばれるのですか?

    まず、Kotlinには、staticメンバのJavaコンセプトは使用されません。これは、Kotlinには、シングルトン状態に関連するプロパティと関数を記述するための独自の objectsの概念 と、Java staticパートがあるためですクラスのをシングルトンの観点からエレガントに表現できます。クラスの名前で呼び出すことができるシングルトンオブジェクトです。したがって、ネーミング:クラスに付属するオブジェクトです。

    以前はその名前は class objectおよびdefault object でしたが、その後 companion objectに名前が変更されました これはより明確で、 Scalaコンパニオンオブジェクト と一貫しています。

    命名のほかに、Java staticメンバよりも強力です。クラスとインターフェイスを拡張でき、他のオブジェクトと同じように参照して渡すことができます。

  • 複数の静的プロパティを作成するには、companion objectブロック内でグループ化する必要がありますか?

    はい、それは慣用的な方法です。または、それらを意味によって非コンパニオンオブジェクトにグループ化することもできます。

    class MyClass {
        object IO {
            fun makeSomethingWithIO() { /* ... */ }
        }
    
        object Factory {
            fun createSomething() { /* ... */ }
        }
    }
    
  • クラスをスコープとするシングルトンインスタンスを即座に作成するために、私はよく/*...*/を作成します。より良い方法は何ですか?

    それはそれぞれの特定の場合に必要なものに依存します。コードは、クラスへの最初の呼び出しで初期化されるクラスにバインドされた状態を保存するのに適しています。

    クラスに接続する必要がない場合は、オブジェクト宣言を使用します。

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

    lazy { ... } delegation を削除して、Java静的初期化子のように、最初のクラスの使用時にプロパティを初期化することもできます。

    シングルトン状態の初期化 の便利な方法もあります。

95
hotkey

なぜ「コンパニオン」と呼ばれるのですか?

このオブジェクトは、インスタンスのコンパニオンです。 IIRCでは、ここで長い議論が行われました: 近日変更クラスオブジェクト再考

複数の静的プロパティを作成するには、コンパニオンオブジェクトブロック内で静的プロパティをグループ化する必要がありますか?

はい。すべての「静的」プロパティ/メソッドは、このコンパニオン内に配置する必要があります。

クラスをスコープとするシングルトンインスタンスを即座に作成するには、次のように記述します。

シングルトンインスタンスをすぐには作成しません。 singletonに初めてアクセスするときに作成されます。

それはそれを行うための単一の方法のように思えます。より良い方法は何ですか?

むしろobject Singleton { }でシングルトンクラスを定義します。参照: オブジェクト宣言Singletonのインスタンスを作成する必要はありません。そのように使用してくださいSingleton.doWork()

Kotlinには、コードを整理するためのその他のものが用意されていることに注意してください。現在、単純な静的関数に代わるものがあります。代わりに最上位関数を使用できます。

17
D3xter

「コンパニオン」と呼ばれる理由

クラス内のオブジェクト宣言は、コンパニオンキーワードでマークできます。

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

クラス名を修飾子として使用するだけで、コンパニオンオブジェクトのメンバーを呼び出すことができます。

val instance = MyClass.create()

「コンパニオン」なしで「オブジェクト」のみを使用する場合、次のようにする必要があります。

val instance = MyClass.Factory.create()

私の理解では、「コンパニオン」とは、このオブジェクトが外部クラスとコンパニオンであることを意味します。

5
Lyn

コンパニオンはJavaのような「静的ブロック」と同じと言えますが、Kotlinの場合、静的ブロックの概念はありません。コンパニオンはフレームに含まれます。

コンパニオンブロックを定義する方法:

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

クラス名で直接、コンパニオンブロックのメソッドを呼び出す

Example.Companion.display
0
Ankur Yadav