幕后属性

62 阅读1分钟

有时候有这种需求,我们希望一个属性:**对外表现为只读,对内表现为可读可写,**我们将这个属性成为幕后属性。 如:

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // 类型参数已推断出
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

_table属性声明为private,因此外部是不能访问的,内部可以访问;外部访问通过table属性,而table属性的值取决于_table,这里_table就是幕后属性。

而且还有一个优点:惰性初始化(懒加载),当第一次访问table时,才会去初始化_table,第二次访问时,也不会重新初始化。

当初始化消耗大量资源,惰性初始化显得特别有价值。

幕后属性这种设计在Kotlin 的的集合Collection中用得非常多,Collection 中有个size字段,size 对外是只读的,size的值的改变根据集合的元素的变换而改变,这是在集合内部进行的,这用幕后属性来实现非常方便。