代码之家  ›  专栏  ›  技术社区  ›  Khemraj Sharma

科特林的单重类

  •  10
  • Khemraj Sharma  · 技术社区  · 7 年前

    我想知道创建singleton类的方法,这样我的Util类在每个应用程序中只实例化一次。然而,当我将Java类转换为kotlin时,生成了下面的代码。

    companion object {
        private var utilProject: UtilProject? = null
    
        val instance: UtilProject
            get() {
                if (utilProject == null) utilProject = UtilProject()
                return utilProject!!
            }
    } 
    

    我能找到一个亲戚 question

    6 回复  |  直到 6 年前
        1
  •  33
  •   Naetmul    7 年前

    只是

    companion object {
        val instance = UtilProject()
    } 
    

    会做这项工作因为 伴星 它本身就是一个语言层次的单体。
    (在 instance 当伴生对象为 第一 呼叫。)

    如果需要调整singleton对象的初始化时间,可以为每个类创建一个对象。

    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 的伴生对象被调用。

    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 
    }
    

    总之,
    一个 object 或者 companion object 是Kotlin中的一个单例对象。
    您可以在 对象 物体 ,然后像使用单变量一样使用变量。

    伴星 在首次使用时实例化。 val var 在一个 第一次实例化(即,当 对象 第一次使用)。

        2
  •  45
  •   dey    6 年前

    object 科特林的单身汉。您只需键入这样简单的内容即可获得工作单例类:

    object MySingleton
    

    object MySingleton {
        fun someFunction(...) {...}
    }
    

    然后使用它:

    MySingleton.someFunction(...)
    

    有一个参考: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

    在你的情况下,你只需要在你的定义中替换 class UtilProject 对此:

    object UtilProject {
    
        // here you put all member functions, values and variables
        // that you need in your singleton Util class, for example:
    
        val maxValue: Int = 100
    
        fun compareInts(a: Int, b: Int): Int {...}
    }
    

    UtilProject.compareInts(1, 2)
    //or
    var value = UtilProject.maxValue
    
        3
  •  5
  •   Michał Powłoka    6 年前

    超级简单的懒惰示例:

    companion object {
        val instance: UtilProject by lazy { UtilProject() }
    }
    
        4
  •  2
  •   Gustavo Wilgenhoff    7 年前

    只需要单词object。

    object UtilProject {
        var bar: Int = 0
        fun foo() {        
        }
    }
    

    直接访问只有一个实例的对象

    fun main(args: Array<String>) {
        UtilProject.bar = 1
        println(UtilProject.bar)    
    }
    
        5
  •  2
  •   Marko Topolnik    6 年前

    在Kotlin中,您应该去掉实用工具singleton类的整个概念。惯用的方法是简单地将所有声明移到顶层。

    public final class Util {
        public static final Util UTIL = new Util();
    
        private int prefixLength = 4;
    
        private Util() {}
    
        public void setPrefixLength(int newLen) {
            prefixLength = newLen;
        }
    
        public String extractVin(String input) {
            return input.substring(prefixLength);
        }
    }
    

    用法:

    String vin = UTIL.extractVin("aoeuVN14134230430")
    

    在Kotlin中只需创建一个名为 util.kt 包括以下内容:

    var prefixLength = 4
    
    fun String.extractVin() = this.substring(prefixLength)
    

    val vin = "aoeuVN14134230430".extractVin()
    

    但是。。。你在污染顶级命名空间!

    如果您的Java直觉在这里触发了一个红旗,请记住 包裹 是命名空间结构,与Java相反,Kotlin没有将命名空间和封装的关注点合并在一起。没有“包私有”访问级别,因此您不必决定某些内容必须保留在同一个包中,这样就可以将其设置为包私有。

    因此,在Java中,您可以创建一个退化类作为解决方法,在Kotlin中,您只需在它自己的包中创建一个文件。

        6
  •  1
  •   onCompletion    6 年前

    一个 Singleton

    object RetrofitClient {
    
        private var instance: Api? = null
        private val BASE_URL = "https://jsonplaceholder.typicode.com/"
    
        fun getInstance(): Api? {
            if (instance == null) {
                val retrofit = Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build()
                instance = retrofit.create(Api::class.java)
            }
            return instance
        }
    }