Search code examples
kotlinkotlin-null-safety

Can a field be cast to non null version of itself?


I have a data class

data class MyModel(private val _data: MyData? = null)

And I want to ensure my data is only accessible when it is not null, else throw. I use the below which is good.

    fun getData(): MyData {
        return checkNotNull(_data) { "data shouldn't be null" }
    }

However, if I follow the guide as per Override getter for Kotlin data class, the below complaints I need to return MyData? instead of MyData

val data = _data
    get(): MyData {
        return checkNotNull(field) { "data shouldn't be null" }
    }

Is it true that field can't be cast to the Non-null version of it when return?


Solution

  • If your goal is to declare a getter for a Any? property that returns a Any, it's not possible. You'll get the following error:

    Getter return type must be equal to the type of the property

    So attempting to do something like

    val test : String?
        get() : String = "hi"
    

    Wouldn't work.


    However, you could hide the nullable property and expose a non-nullable property which references the nullable value via casting:

    private val test : String? = "hi"
    val testNotNull : String = test as String
    

    If test referenced null, an exception will be thrown.

    For example:

    fun main(args: Array<String>) = print(Demo().testNotNull)
    
    class Demo(private var test: String? = "hi") {
        val testNotNull : String
    .       get() = test as String
    }
    

    You can test this snippit out at try.kotlin.org

    Although this is not safe. You should rethink your design. If you're not interoping with Java, you shouldn't punish yourself with nullable types.