请不要怪我。我只是从Java迁移到Kotlin。我正尝试在Singleton.getInstance().someMethod()
的帮助下以常规java方式创建单例,并发现在Kotlin中可以使用几种不同的方法:
对象(单独的文件)object Singleton
伴侣对象companion object Factory {}
私有构造函数
class Singleton private constructor()
那么,请您帮我一下,解释一下我们在哪里可以输入什么类型?
答案 0 :(得分:1)
object Singleton
companion object Factory {}
class Singleton private constructor()
我认为您不需要kotlin中的单例,因为kotlin已经提供了开箱即用的良好单例选项,但是正如其他SO用户所述,私有构造函数在kotlin中的作用与例如在java-防止实例化。再说一遍,如果您想在Kotlin中创建类似类的utils,请更好地考虑使用扩展功能。
PS ::应该很明显,所以我要提-上面的内容中有99%是从https://kotlinlang.org/docs/reference/object-declarations.html粘贴复制的-也许它有更好的机会在此处进行更多搜索:)>
答案 1 :(得分:0)
如果您需要一个单例-一个只有一个实例的类-您可以按通常的方式声明该类,但可以使用object关键字而不是class。 如果需要将函数或属性绑定到类而不是实例(类似于Python中的@staticmethod),则可以在同伴对象中声明它。
当没有实例字段或方法(例如Math类)或调用方法以获取类的实例时,专用构造函数用于防止创建类的实例。
答案 2 :(得分:0)
Kotlin中的对象就像Java中的静态类。它们通常用于构造单例模式:
object Singleton
Java中的等效项是:
public static class Singleton{}
companion object
用于必须应用Factory模式或静态工厂模式的情况(如您的伴随对象名称所述)。
假设我们使用Java:
public class Fragment(){
private Fragment(){}
public static Fragment newInstance(){
return new Fragment();
}
}
与Kotlin中的等效:
class Fragment private constructor(){
companion object{
fun newInstance() = Fragment()
}
}
companion object
也是一个对象,但是通过单词companion
告诉JVM,该object
所在的一个类可以访问其中的所有内容。
因此,如果您尝试从Java代码中调用它,它将是这样的:
Fragment.Companion.newInstance()
上面的示例实际上也适用于私有构造函数。 基本上,即使在Java中,当您不需要直接访问构造函数时,只需将构造函数标记为私有并使用静态工厂方法即可。
关于您的问题,使用上面提供的信息:
要实现
Singleton.getInstance().someMethod()
确切地说,您必须执行以下操作:
class Singleton private constructor(){
companion object{
fun getInstance() = Singleton()
fun someMethod(){ /* Your implement here */}
}
}
但是Kotlin风格并不太复杂。
只需:
object Singleton{
fun someMethod(){ /* Your method here */}
}
然后就叫它:
Singleton.myMethod()
编辑:关于您的SharedPreferences
问题,我不建议您使用object
。您需要上下文和共享首选项模式的构造函数。因此,我将采用这样的方式(假设由于您在评论中提到了匕首,因此您一直在使用它):
class SharedPreferencesHelper @Inject constructor(val context: Context, val mode: Int) // not sure about the mode type but check the docs {
private lateinit var sharedPreferences: SharedPreferences
private lateinit var sharedPreferencesEditor: SharedPreferences.Editor
init{
sharedPreferences = context.getSharedPreferences("filename", mode)
sharedPreferencesEditor = sharedPreferences.edit()
}
}
然后,您只需在需要的任何构造函数中调用它即可。
或者:
class SharedPreferencesHelper private constructor(){
private lateinit var sharedPreferences: SharedPreferences
private lateinit var sharedPreferencesEditor: SharedPreferences.Editor
companion object {
fun startSharedPrefs(context: Context, fileName: String, mode: Int) = SharedPreferencesHelper().apply{
sharedPreferences = context.getSharedPreferences(fileName, mode)
sharedPreferencesEditor = sharedPreferences.edit()
}
}
}
然后在匕首模块中启动它:
@Module
object SharedPrefsModule{
@Singleton
@Provides
fun provideSharedPreferences(application: Application) =
SharedPreferencesHelper.startSharedPrefs(application, "fileName", MODE_PRIVATE)
}
然后在需要的地方调用依赖项