Search code examples
androidkotlinandroid-livedatamutablelivedataandroid-livedata-transformations

Why declare mutableLiveData class with val type?


Why not use mutableLiveData of the val type as a substitute for the var type?

Isn't it a violation to be able to set on the val type?


Like, for example:

  1. Example of a val type
class LoadDetailViewModel : ViewModel() {

    private val _liveData = MutableLiveData<String>()
    val liveData: LiveData<String> get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = "value"
        _liveData.postValue("value")
    }
}

  1. Code changed to var type
class LoadDetailViewModel : ViewModel() {

    private var _liveData = MutableLiveData<String>()
    var liveData: LiveData<String> get() = _liveData

    fun loadData() = viewModelScope.launch {
        _liveData.value = "value"
        _liveData.postValue("value")
    }
}

But the result is still equivalent. There is no error when I declare mutableLiveData as var, but I don't know why I have to declare it as val.


  • I understand that the val type in the Kotlin language is an immutable type, and the var type is a mutable type.
  • Then isn't it right to declare it as a var type?

Android Developers I looked up the official documents of Android, but there was no answer to them.


Solution

  • When you call _liveData.value = "value", notice you are not using _liveData =. So you are not mutating the property _liveData and it doesn't need to be a var. You are mutating the property inside the MutableLiveData.

    It is wrong to use var for this, because you are not swapping out the instance of MutableLiveData. If you changed it to a different instance, your observers would not be notified.

    You are confusing mutability of the property (the thing that holds a reference to an instance of MutableLiveData) with the class (the MutableLiveData itself). MutableLiveData is a mutable class because it has mutable variables inside it. You can mutate it, but you don't want to mutate the property that is holding a reference to it.

    Using var isn't causing any problems because you haven't actually utilized the mutability to change the reference to a different instance. But since you should never want to do that, there is no reason to use var instead of val. It makes code clearer and more robust to use val.