Reputation: 21
What's an idiomatic way to do code this in Kotlin?
private var someVar: SomeClass? = null
private fun getSomeVar(): SomeClass {
if (someVar == null) {
someVar = getDefaultSomeVar()
}
return someVar
}
Android Studio warns me about the return type. In Java this code is, however, proper and idiomatic. I mean, instead of changing the return type to SomeClass?
maybe there's still a better way?
Actually, getSomeVar()
can never return null
Upvotes: 2
Views: 207
Reputation: 2169
It could be shorter and without any warnings
private fun getSomeVar(): SomeClass {
return someVar?:getDefaultSomeVar()
}
Upvotes: 0
Reputation: 6495
The compiler complains because, theoretically, a different thread could change someVar
in between the assignment and the return statement.
The idiomatic solution here would be to use property delegation:
private val someVar: SomeClass by lazy { getDefaultSomeVar() }
This initializes the property when it is first accessed in a thread safe manner. Also note that it is now a non-nullable val, instead of a nullable var, which makes it generally easier to work with.
You do lose the ability to modify it later on. If it needs to be mutable you currently have to make that yourself. For an example implementation see this SO question: Kotlin lazy default property
The following two solutions take the method in the question (the 'java way') for granted and just show a way to prevent the compiler warning. However, in your situation these are not advised as they both have drawbacks over the lazy initialized property:
1) Introduce a local variable. This variable is safe from being mutated by other threads and allows the compiler to do a Smart Cast:
private fun getSomeVar(): SomeClass {
var value = someVar
if(value == null) {
value = getDefaultSomeVar()
someVar = value
}
return value
}
The method itself is however still not thread safe. In a multithreaded environment, getDefaultSomeVar()
could be called multiple times and it is not guaranteed that the returned value of this method is equal to someVar
.
2) Use !!
: the double bang operator. This converts a nullable type to non-nullable. But now you lose the protection and null safety that the kotlin compiler enforces on you.
return someVar!!
As the documentation puts it: 'If you want an NPE, you can have it'
Upvotes: 5
Reputation: 1314
You can write:
return someVar!!
this will return a non-null value, however if it's null it will throw an NPE.
Upvotes: 0