Kotlin property delegates do not infer types based on the property they’re associated with. For example:
import java.util.Scanner
fun methodThatReturnsAPlatformType() = Scanner("").findInLine("") // Returns type String!
fun main(args: Array<String>) {
//sampleStart
val property: String by lazy { methodThatReturnsAPlatformType() } // Returns Lazy<String!>
println(property) // Should throw IllegalStateException if `property` value is null
//sampleEnd
}
Now if we simply assigned the property instead of a Lazy delegate, we get the correct error:
import java.util.Scanner
fun methodThatReturnsAPlatformType() = Scanner("").findInLine("") // Returns type String!
fun main(args: Array<String>) {
//sampleStart
val property: String = methodThatReturnsAPlatformType() // Returns String!
println(property)
//sampleEnd
}
To work around this issue, we can explicitly set the type param for the delegate, val property = lazy<String>
.
This StackOverflow question shows a case where @kolossal ran into this issue.
I believe this should be changed so that delegates returning a platform type should have an extra null check. All other cases where a non-nullable property is assigned a null value throws an error, so should delegates.
This example is in direct opposition to this paragraph from the Kotlin docs (https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types):
If we choose a non-null type, the compiler will emit an assertion upon assignment. This prevents Kotlin’s non-null variables from holding nulls. Assertions are also emitted when we pass platform values to Kotlin functions expecting non-null values etc. Overall, the compiler does its best to prevent nulls from propagating far through the program (although sometimes this is impossible to eliminate entirely, because of generics).