如何优雅实现无消耗的属性懒加载?


#1

以下是我研究的几种懒加载方法:(String只是作为例子,真实情况下可能是其它类)

  1. open class P {
        protected var str:String? = null
        get() {
            if (field == null){
                field = String()
            }
            return field
        }
    }
    

    这应该是最理想的,但是子类访问的时候还得使用断言str!!来确保不为空,比较繁琐。

  2. 第二种使用lazy()

    open class P {
        protected val str:String by lazy { String() }
    }
    

    使用lazy代码比较简洁美观,但是lazy本质上还是生成了一个代理类实例,

    而且对于lazy属性的赋值成功与否判断我好像也没找到很好的办法(了解的麻烦告知下,谢谢),所以也有点问题。

  3. 最后一种就是使用方法了

    open class P {
        private var str: String? = null
        fun getStr(): String {
            if (str == null) {
                str = String()
            }
            return str!!
        }
    }
    

    方法和第一种比较主要是可以在内部实现断言,所以子类调用可以不用判空。但是感觉方法代码和属性脱离了,属性一多不好管理,而且感觉这种写法有点类似java了。

不知道有没有更好的实现方式呢?


#2

最近在学习swift,好像swift可以直接在属性后面加“!”,然后通过类似第一种方式来实现需求,这样看来,swift好像又香了一些。


#3

lazy 有什么问题吗


#4

已经说了呀。lazy会生成一个代理类的实例,而且我无法得知lazy属性是否被赋值了。


#5

还见过这样的

private lateinit var _v: String

    val v: String
        get() = {
            if (!::_v.isInitialized) _v = "1"
            _v
        }()


#6

只要控制 类初始化完成后 ,再访问 被lazy委托的属性就没问题


#7

哈哈 这个有点秀


#8

您误会我的意思了,我的意思是这种情况

open class P {
    protected val bitmap:Bitmap by lazy { Bitmap() }
              
    fun release(){
        // 这里我不知道怎么判断
        if(bitmap is 被代理了){
             bitmap.recycle()
        }
    }
}

class Bitmap{
   fun recycle()
}

#9

啊?我有点不明白,为什么要判断呢 当成普通属性用鸭

可以这样判断:
::bitmap.javaField.type == Lazy::class.java


#10

不要被局限了,lazy 不一定非要跟 by 关键字一起用

open class P {
    protected val strLazy: Lazy<String> = lazy { String() }
}

这样不就达到你的目的了吗,strLazy.isInitialized() 判断是否已初始化,strLazy.value 从里面取值


#11

感觉这样的话还是子类访问还是比较麻烦。刚才在stackoverflow上面看到一个trick,但是要用到reflect相关的东西https://stackoverflow.com/questions/42522739/kotlin-check-if-lazy-val-has-been-initialised


#12

我的意思是判断这个lazy属性是否被初始化了,可能是我表达不清楚。刚在stackoverflow上面这个回答感觉能满足我的要求,https://stackoverflow.com/questions/42522739/kotlin-check-if-lazy-val-has-been-initialised。感谢!


京ICP备16022265号-2 Kotlin China 2017 - 2018