1. ホーム
  2. android

Kotlinのシングルトン・クラス

2023-08-24 05:50:43

質問

Kotlinでシングルトンクラスを作成し、Utilクラスがアプリの実行ごとに一度だけインスタンス化する方法を知りたいです。しかし、Javaクラスをkotlinに変換したところ、以下のようなコードが生成されました。

これは正しいのでしょうか?

companion object {
    private var utilProject: UtilProject? = null

    val instance: UtilProject
        get() {
            if (utilProject == null) utilProject = UtilProject()
            return utilProject!!
        }
} 

関連する 質問 が、それはパラメータ付きであり、私はそれがパラメータなしで変換されていない取得しています。

どのように解決するのですか?

ただ

companion object {
    val instance = UtilProject()
} 

はその役割を果たします。 コンパニオンオブジェクト 自体が言語レベルのシングルトンであるためです。

(その instance はコンパニオンオブジェクトが 最初 が呼び出されたときに作成されます)。

-- 更新された --

シングルトンオブジェクトが初期化されるタイミングを制御する必要がある場合、各クラスに対して1つのオブジェクトを作成することができます。

class UtilProject {
    ....
    companion object {
        val instance = UtilProject()
    }
}

class AnotherClass {
    ...
    companion object {
        val instance = AnotherClass()
        const val abc = "ABC"
    }
}

fun main(args: Array<String>) {
    val a = UtilProject.instance // UtilProject.instance will be initialized here.
    val b = AnotherClass.abc // AnotherClass.instance will be initialized here because AnotherClass's companion object is instantiated.
    val c = AnotherClass.instance
}

ここで AnotherClass.instance が初期化される前に AnotherClass.instance が実際に呼ばれる前に初期化されます。初期化されるのは AnotherClass のコンパニオン・オブジェクトが呼ばれたときに初期化されます。 必要なときに先に初期化されないようにするには、次のようにすればよい。

class UtilProject {
    ....
    companion object {
        fun f() = ...
    }
}

class AnotherClass {
    ...
    companion object {
        const val abc = "ABC"
    }
}

object UtilProjectSingleton {
    val instance = UtilProject()
}

object AnotherClassSingleton {
    val instance = AnotherClass()
}

fun main(args: Array<String>) {
    UtilProject.f()
    println(AnotherClass.abc)

    val a = UtilProjectSingleton.instance // UtilProjectSingleton.instance will be initialized here.
    val b = AnotherClassSingleton.instance // AnotherClassSingleton.instance will be initialized here.

    val c = UtilProjectSingleton.instance // c is a.
}

各シングルトンの初期化タイミングを気にしないのであれば、このような使い方も可能です。

class UtilProject {
    ....
    companion object {
        fun f() = ...
    }
}

class AnotherClass {
    ...
    companion object {
        const val abc = "ABC"
    }
}

object Singletons {
    val utilProject = UtilProject()
    val anotherClass = AnotherClass()
}

fun main(args: Array<String>) {
    val a = Singletons.utilProject
    val b = Singletons.anotherClass 
}

まとめると

an object または companion object はKotlinでは1つのシングルトンオブジェクトです。

の中に変数を代入することができます。 オブジェクト または オブジェクト で、その変数をシングルトンと同じように使用します。

object または companion object は最初に使われるときにインスタンス化されます。 valvar の中に object が初期化されるとき object が最初にインスタンス化されたとき (すなわち object が最初に使われたとき)。