Could val properties expose a supertype without a backing property?

val properties do the job in replacing a Java final member and a public getter.
What’s not possible however is exposing a supertype instead of the raw type:

private final ArrayList<String> list = new ArrayList<>();

public List<String> getList() {
     return list;
}

In Kotlin you must use a backing property of a different type, for each of this fields that the class wants to expose, for each class, and try to find a readable naming convention that feels pleasant.

But this is so common (working on a mutable type inside the class itself and exposing the non mutable type, is just the most common example) that it might deserve a language addition?

I am being generic as I’m not a language designer, and there are some caveats to be figured out, but the point is for the non-private val property to define a supertype for anyone outside the class or file. Random examples :

class Tree {
    val fruits = mutableListOf<Fruit>()
        exposes List<Food>

    val fruits = mutableListOf<Fruit>()
        exposed type = List<Food>
}

And to clarify, I intend this.fruits to return a MutableList<Fruit> (backed by a private java field), and tree.fruits to return a List<Food> (backed by java getter) when the non-private visibility is being leveraged.

There is issue for this: https://youtrack.jetbrains.com/issue/KT-14663
You can vote for it.

Reply this old post instead of create a same post.

Same problem here when use LiveData, need a better solution:

    private val mutableAnyLiveData: MutableLiveData<Any> = MutableLiveData()

    @JvmField
    val anyLiveData: LiveData<Any> = mutableAnyLiveData // expose super type for public access.

1 Like