Reputation: 2607
Please don't blame me. Im just moving from Java to Kotlin. I'm trying to create a singleton as a regular java way with help of Singleton.getInstance().someMethod()
and have found that in Kotlin there are several different things you can use:
Object (separate file) object Singleton
Companion object companion object Factory {}
Private constructor
class Singleton private constructor()
So can you please help me and explain where we can you what type?
Upvotes: 2
Views: 4793
Reputation: 8371
Objects in Kotlin are like static classes in Java. They are usually used to construct the singleton pattern:
object Singleton
The equivalent in Java would be:
public static class Singleton{}
The companion object
is used in cases (as your companion object name states) where you have to apply the Factory pattern or the static factory pattern.
Let's suppose we have this in Java:
public class Fragment(){
private Fragment(){}
public static Fragment newInstance(){
return new Fragment();
}
}
The equivalent of that in Kotlin would be:
class Fragment private constructor(){
companion object{
fun newInstance() = Fragment()
}
}
The companion object
is also an object but through the word companion
is just telling JVM that the one class in which this object
is, has access to everything inside it.
Therefore if you try to call it from Java code, it would be something like this:
Fragment.Companion.newInstance()
The above example actually also fits for private constructor. Basically, even in Java, when you don't need to access the constructor directly, just mark the constructor as private and use a static factory method.
Regarding your question, with the information provided above:
To achieve
Singleton.getInstance().someMethod()
with exactly this call, you have to do this:
class Singleton private constructor(){
companion object{
fun getInstance() = Singleton()
fun someMethod(){ /* Your implement here */}
}
}
However that's not too sophisticated in Kotlin style.
Just do:
object Singleton{
fun someMethod(){ /* Your method here */}
}
Then just call it:
Singleton.myMethod()
EDIT: Regarding your question of SharedPreferences
I don't suggest to use an object
for that. You need the constructor for the context and perhaps shared preferences mode. Therefore I would go with something like this (assuming that you are using dagger since you mentioned it in comment):
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()
}
}
Then you just call it in any constructor you need it.
Or:
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()
}
}
}
Then start it in a dagger module:
@Module
object SharedPrefsModule{
@Singleton
@Provides
fun provideSharedPreferences(application: Application) =
SharedPreferencesHelper.startSharedPrefs(application, "fileName", MODE_PRIVATE)
}
Then call the dependency wherever you need it
Upvotes: 2
Reputation: 3500
object Singleton
companion object Factory {}
class Singleton private constructor()
I don't think you need that for singleton in kotlin as kotlin already provides good singleton option out of the box, however as stated by other SO user here private constructor is serving the same purpose in kotlin as in, for example, java - to prevent instantiation. As a second thought, if you think of creating utils like classes in kotlin, please better consider using extension functions.
PS.: it should be pretty obvious so I'll mention it - 99% of the above is brutally copy-pasted from https://kotlinlang.org/docs/reference/object-declarations.html - may be it has better chances to be more searchable here:)
Upvotes: 1
Reputation: 11
If you need a singleton - a class that only has got one instance - you can declare the class in the usual way, but use the object keyword instead of class. If you need a function or a property to be tied to a class rather than to instances of it (similar to @staticmethod in Python), you can declare it inside a companion object.
Private constructors are used to prevent creating instances of a class when there are no instance fields or methods, such as the Math class, or when a method is called to obtain an instance of a class.
Upvotes: 0