代码之家  ›  专栏  ›  技术社区  ›  Ruslan Akhundov

Kotlin:在getter中使用mutable时从getter返回不可变集合[重复]

  •  3
  • Ruslan Akhundov  · 技术社区  · 7 年前

    我有一些字段是collection,它可以在包含它的服务中发生变化,而其他一些服务应该能够访问它,而不可能自己改变它。

    在Java中,它可以像这样实现:

    public class Test {
    
        private final List<Integer> list = new ArrayList<>();
    
        public List<Integer> getList() {
            return Collections.unmodifiableList(list);
        }
    }
    

    在Kotlin中,我存储声明为 MutableList :

    val someCollection: MutableList<Int> = ArrayList()
        get() = unmodifiableList(field)
    

    但是getter显然会返回类型为的对象 可变列表

    理想情况下,我希望实现以下目标:

    val someCollection: MutableList<Int> = ArrayList()
            get() = unmodifiableList(field) as List // <-- returns List instead of MutableList
    

    换句话说,可以更改生成的getter的签名以返回另一个接口。答案很可能是否定的,我想知道为什么?这被认为是一些不好的做法吗?

    我发现有可能这样做:

    private val _someCollection: MutableList<Int> = ArrayList()
    val someCollection: List<Int>
        get() = unmodifiableList(field)
    

    但它看起来比手工创建getter还要糟糕,因为它创建了更多的字段。

    1 回复  |  直到 7 年前
        1
  •  1
  •   hotkey    7 年前

    不,这在科特林目前是不可能的。实际上,当前的设计强制getter具有与整个属性相同的返回类型。

    通常,如您注意到的,解决方法是使用支持属性。

    或者,可以使用 List 属性,用 MutableList 在类中,并使用接口公开类的实例:

    interface SomeInterface {
        val someList: List<Int>
    }
    
    internal class SomeClass : SomeInterface {
        override val someList: MutableList<Int> = mutableListOf()
    }
    
    fun getSomeInterface(): SomeInterface =
        SomeClass().apply { someList += listOf(1, 2, 3) }
    

    见: a related discussion .