println(e.p)
打印结果:
Example@33a17727, thank you for delegating ‘p’ to me!
同样,当您分配给 p
时,setValue()
将调用该函数。前两个参数是相同的,第三个保存被分配的值:
e.p = “NEW”
打印结果:
NEW has been assigned to ‘p’ in Example@33a17727.
标准库中的代理
懒惰属性
lazy()
是一个函数,它接受一个 lambda
并返回一个实例,Lazy<T>
该实例可以作为实现惰性属性的委托:第一次调用 get()
执行传递给的 lambdalazy()
并记住结果,随后的调用 get()
只返回记住的结果。
val lazyValue: String by lazy {
println(“computed!”)
“Hello”
}
fun main() {
println(lazyValue)
println(lazyValue)
}
默认情况下,惰性属性的评估是同步的:该值仅在一个线程中计算,所有线程将看到相同的值。如果不需要同步初始化委托,以便多个线程可以同时执行,则 LazyThreadSafetyMode.PUBLICATION
作为参数传递给 lazy()
函数。
如果您确定初始化将始终发生在与您使用该属性的线程相同的线程上,则可以使用 LazyThreadSafetyMode.NONE
:它不会产生任何线程安全保证和相关开销。
lateinit 和 by lazy 的区别
我的理解是我们平时在项目中尽量少用 lateinit
,因为很多东西我们是确定怎么初始化他的,这个时候只需要延迟初始化,使用 by lazy
就可以了。lateinit
我能想到的应用场景就是外部传了一个变量来初始化某个属性而且必不为空。由于 kotlin
和 swift
一样,有着严格的检查,我们可以利用它来告诉编译器,我们要晚一点才能初始化它。这个也是在 swift
中不能优雅解决的一个点。
最近在看公司内部的项目,这个关键字被滥用了,看着贼难受。唉。。。
可观察属性
Delegates.observable()
接受两个参数:初始值和修改的闭包。 每次分配给属性时都会调用闭包(在执行分配之后)。它具有三个参数:被分配的属性、旧值和新值:
class User {
var name: String by Delegates.observable(“”) {
prop, old, new ->
println(“$old -> $new”)
}
}
fun main() {
val user = User()
user.name = “first”
user.name = “second”
}
如果您想拦截分配并否决它们,请使用 vetoable()
代替 observable()
。
委托给另一个属性
一个属性可以把他的 setter()
和 getter()
代理给另一个属性。这种代理可以用于 top-level
和 class
属性(成员或者扩展)。这种代理属性可以是:
- 一个
top-level
属性 - 同一个类中的成员属性或者扩展属性
- 不同类中的成员属性或者扩展属性
像这种把一个属性委托给别一个属性的情况,要用 ::proper
的语法
var topLevelInt: Int = 0
class ClassWithDelegate(val anotherClassInt: Int)
class MyClass(var memberInt: Int, val anotherClassInstance: ClassWithDelegate) {
var delegatedToMember: Int by this::memberInt
var delegatedToTopLevel: Int by ::topLevelInt
val delegatedToAnotherClass: Int by anotherClassInstance::anotherClassInt
}
var MyClass.extDelegated: Int by ::topLevelInt
这个其实是很有用的。举个例子,如果我们想以向后兼容的方式重命名属性时:引入一个新的属性,用注释对旧属性进行 @Deprecated
注释,然后委托其实现。
class MyClass {
var newName: Int = 0
@Deprecated(“Use ‘newName’ instead”, ReplaceWith(“newName”))
var oldName: Int by this::newName
}
fun main() {
val myClass = MyClass()
// Notification: ‘oldName: Int’ is deprecated.
// Use ‘newName’ instead
myClass.oldName = 42
println(myClass.newName) // 42
}
上述两个例子是官方文档(1.5.10)提供的用法,老版本的 kotlin 是不支持的
属性代理
对于只读属性 val
,委托应提供 getValue()
具有以下参数的运算符函数:
thisRef
必须是属性所有者的相同或超类型(对于扩展属性,它应该是被扩展的类型)。
property
必须是类型 KProperty<*>
或其超类型。
getValue()
必须返回与属性(或其子类型)相同的类型。
class Owner {
val valResource: Resource by ResourceDelegate()
}
class ResourceDelegate {
operator fun getValue(thisRef: Owner, property: KProperty<*>): Resource {
return Resource()
}
}
对于可变属性 var
,委托必须额外提供 setValue()
具有以下参数的运算符函数:
thisRef
必须是属性所有者的相同或超类型(对于扩展属性,它应该是被扩展的类型)。
property
必须是类型 KProperty<*>
或其超类型。
value
必须与属性(或其超类型)具有相同的类型。
getValue()
/setValue()
函数可以作为委托类的成员函数或扩展函数提供。当您需要将属性委托给最初不提供这些功能的对象时,后者很方便。这两个函数都需要用 operator
关键字标记。
您可以将委托创建为匿名对象,而无需使用接口 ReadOnlyProperty
和 ReadWritePropertyKotlin
标准库创建新类。它们提供了所需的方法:getValue()
在 ReadOnlyProperty
中声明,ReadWriteProperty
扩展它并添加 setValue()
。因此,您可以在需要传递 ReadOnlyProperty
的时候传递 ReadWriteProperty
。
fun resourceDelegate(): ReadWriteProperty<Any?, Int> =
object : ReadWriteProperty<Any?, Int> {
var curValue = 0
override fun getValue(thisRef: Any?, property: KProperty<>): Int = curValue
override fun setValue(thisRef: Any?, property: KProperty<>, value: Int) {
curValue = value
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
文章不易,如果大家喜欢这篇文章,或者对你有帮助希望大家多多点赞转发关注哦。文章会持续更新的。绝对干货!!!
- Android进阶学习全套手册
关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
-
Android对标阿里P7学习视频
- BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
合跨平台开发,等
[外链图片转存中…(img-weZDFYxR-1712797524156)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-5xqcLEfW-1712797524156)]