委托属性

kotlin提供了将属性委托到一个类的方法,就是委托属性。
当我们使用属性的get和set方法时,属性委托的getValue和setValue就会被调用。
属性委托的结构如下:
class Delegate<T> : ReadWriteProperty<Any?, T>{override fun getValue(thisRef: Any?, property: KProperty<*>): T{return ...}override fun setValue(thisRef: Any?, property: KProperty<*>, value: T){...}
}

其中T是委托属性的类型,getValue接收一个类的引用和一个属性的元数据,setValue多接收一个设置的值。

使用by关键字来委托属性,如下:
class Example {var p: String by Delegate()
}

一、标准委托

kotlin标准库中有一系列标准委托,我们可以直接使用,可以应付大部分情况。当然我们也可以自定义委托。

1、Lazy

需要提供一个lambda,当第一次执行getValue时会执行这个lambda进行初始化,之后再调用getValue会返回同一个值。所以委托的属性可以延迟进行初始化,在真正使用前可以不必初始化。如:
class App : Application{val database: SQLiteOpenHelper by lazy{MyDatabaseHelper(applicationContext)}override fun onCreate(){super.onCreate()var db = database.writableDatabase}
}

所以只要当在onCreate中使用时才去初始化,而这时候applicationContext已经存在了。

lazy是线程安全的。如果不担心多线程问题,可以使用lazy(LazyThreadSafeMode.NONE){ ... }来提高性能
同时要注意委托lazy的属性必须是不可变变量,既val修饰,如果用var修饰会报编译错误。

2、Observable

这个委托会检测值的变化,当属性的set方法被调用,会自动执行我们指定的lambda表达式。一旦属性被赋予了新值,我们就会接收到被委托的属性、旧值和新值。如:
class ViewModel(val db: MyDatabase){var name by Delegates.observable(""){d, old, new -> db.saveChange(this, new)}
}

这个例子中一旦值被修改就会保存到数据库中。

注意Delegates.observable("")中传的是设定的初始值

3、Vetoable

这是一个特殊的Observable,通过指定的lambda表达式来确定是否保存新值。如
var name by Delegates.vetoable(0){d, old, new -> new >= 0
}

例子中表示只有新值是正数时才保存

4、NotNull

有时候使用属性前可能未初始化,比如像activity这类无法在构造函数中初始化属性的情况。通常我们会定义一个可为null的变量并初始化为空,在每次使用之前做判空。kotlin中还有另外一种方法,使用委托属性NotNull,如:
var name: String by Delegates.notNull()
如果赋值前使用时会抛出一个错误。
(目前这个方案与初始化为Null一样都在使用前要进行判断,否则抛出错误,所以不太能get到使用的点在哪里)

5、从Map中委托值

可以将属性委托到一个map,属性的值会从map中获取,属性的名字对应map中的key。
注意不同版本的区别
在有的版本中,需要import kotlin.properties.getValue 或 kotlin.properties.setValue
在kotlin-stdlib:1.1.2-4中则不需要,但是不能直接使用map,如:
class Config (map: HashMap<String, Any?>){var name: String by mapvar id: Int by map
}var config = Config(hashMapOf("name" to "test","id" to 12
))

二、自定义委托

参照文章开始
自定义委托必须实现ReadWriteProperty或ReadOnlyProperty,取决于被委托对象是var还是val。
然后重写setValue和getValue方法即可。
使用时可以直接使用(参考文章开始)
也可以像Delegates那样集中定义函数,如:
object DelegatesExt{fun notNullSingle<T>() : ReadWriteProperty<Any?, T> = NotNullSingle()   //NotNullSingle是我们自定义的委托}

kotlin学习笔记——委托属性相关推荐

  1. Kotlin 学习笔记(七)—— Kotlin类与对象之属性与字段

    Kotlin 学习笔记(七)-- Kotlin类与对象之属性与字段 Kotlin学习笔记系列教程 Kotlin 学习笔记(一)-- 概述.学习曲线.开发工具.参考资料 Kotlin 学习笔记(二)-- ...

  2. Kotlin学习笔记(3)- 语法

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步!kotlin学习笔记系列首发简书和CSDN Kotlin学习笔记(1)- 环 ...

  3. Kotlin学习笔记(2)- 空安全

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步!kotlin学习笔记系列首发简书和CSDN Kotlin学习笔记(1)- 环 ...

  4. Kotlin学习笔记19 阶段复习1

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 基础部分 Kotlin学习笔记 第一章开始 第二章 基础_积跬步 至千里-CSDN博客 类与继承 Kotlin学习笔记 第 ...

  5. Kotlin 学习笔记(八)—— Kotlin类与对象之接口

    Kotlin 学习笔记(八)-- Kotlin类与对象之接口 Kotlin学习笔记系列教程 Kotlin 学习笔记(一)-- 概述.学习曲线.开发工具.参考资料 Kotlin 学习笔记(二)-- 基础 ...

  6. Kotlin学习笔记(1)- 环境配置

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正.如果你觉得我的文章对你有用,欢迎关注我,我们一起学习进步!kotlin学习笔记系列首发简书和CSDN Kotlin学习笔记(1)- 环 ...

  7. Kotlin学习笔记20 阶段复习2

    参考链接 示例来自bilibili Kotlin语言深入解析 张龙老师的视频 lambda表达式 内联函数 Kotlin学习笔记 第三章 函数 高阶函数 lambda表达式 内联函数_积跬步 至千里- ...

  8. Kotlin学习笔记12——数据类和密封类

    Kotlin学习笔记12--数据类和密封类 前言 数据类 在类体中声明的属性 复制 componentN 解构声明 密封类 尾巴 前言 上一篇,我们学习了Kotlin中的拓展,今天继续来学习Kotli ...

  9. Kotlin 学习笔记(四)—— 协程的基础知识,面试官的最爱了~

    又是一个月没见了,坚持永远是世上最难的事情,但,往往难事才会有更大的收获.与君共勉~ 前段时间一直在学习 Compose,所以导致 Kotlin 笔记系列搁置了好久.一方面是因为 Compose 的学 ...

最新文章

  1. 关于“中国大妈”的用户画像
  2. 数据处理中的准确性问题
  3. 【01】什么是AJAX
  4. 电子版,材料获取说明
  5. 第3步 (请先看第2步再看第3步) 新建完spring+springmvc+mybatis项目 需要推送gitee仓库进行管理 巨详细
  6. android oreo 源码,android – Oreo:如何在源代码中找到所有受限制的系统调用?
  7. 索引-python核心技术-pyhui版
  8. linux下c 调用python,在Linux下使用python ctypes调用io\u submit
  9. 从零开始学前端:伪元素和盒子模型 --- 今天你学习了吗?(CSS:Day13)
  10. 请不要滥用SharedPreference
  11. dism++封装系统使用教程_【原创】最新WIN10系统封装教程2019系列(一)——定制母盘...
  12. 视频教程-数据结构实战完全手册-C/C++
  13. python实现whois查询_python3实现域名查询和whois查询
  14. selenium网页截图总结
  15. java订单到期自动取消_订单自动过期实现方案
  16. xposed android debug,Android 手机开启全局调试xposed插件
  17. 富途入金步骤记录(个人使用)
  18. rac集群状态中监听状态CHECK TIMED OUT处理
  19. 以太坊源码分析:fetcher模块和区块传播
  20. 1044 Shopping in Mars(柳神39行代码+详细注释)

热门文章

  1. 应用Strong Name保存.NET应用程序集
  2. 用servlet校验密码2
  3. java merge json出错删除相同的json
  4. 【计算机网络】详解HttpURLConnection
  5. 转:Hash, MAC,HMAC说明
  6. 基础 - jQuery选项卡
  7. ScrollView 分割屏幕效果
  8. 线段树专辑 —— pku 2482 Stars in Your Window
  9. 【LeetCode】405 Convert a Number to Hexadecimal (java实现)
  10. Debug javascript inside jsp page 调试jsp嵌入的js