this.fullname$delegate = LazyKt.lazy((Function0)(new Function0() {
@NotNull
public final String invoke() {
return name + lastname;
}
}));

让我们来观察 lazy() 的源码。由于 lazy() 函数默认使用 LazyThreadSafetyMode.SYNCHRONIZED 参数,因此它将返回一个 SynchronizedLazyImpl 类型的 Lazy 对象:

public actual fun lazy(initializer: () -> T): Lazy =
SynchronizedLazyImpl(initializer)

当属性代理第一次被访问时,SynchronizedLazyImplgetValue() 函数就会被调用,这个函数将会在一个 synchronized 块中对属性进行初始化:

override val value: T
get() {
val _v1 = _value
if (_v1 !== UNINITIALIZED_VALUE) {
@Suppress(“UNCHECKED_CAST”)
return _v1 as T
}

return synchronized(lock) {
val _v2 = _value
if (_v2 !== UNINITIALIZED_VALUE) {
@Suppress(“UNCHECKED_CAST”) (_v2 as T)
} else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}

这样就能保证惰性对象会以线程安全的方式初始化,但同时也引入了由 synchronized 块带来的额外开销。

注意: 如果您确定资源会在单线程中被初始化,您可以向 lazy() 传入 LazyThreadSafetyMode.NONE,这样函数就不会在惰性初始化时使用 synchronized 块。不过请记住,LazyThreadSafetyMode.NONE 不会改变惰性初始化的同步特性。由于惰性初始化是同步的,所以在第一次访问时仍会消耗与非惰性初始化过程相同的时间,这意味着那些初始化过程较为耗时的对象仍会在被访问时阻塞 UI 线程。

1val lazyValue: String by lazy(LazyThreadSafetyMode.NONE) {“lazy”}

惰性初始化可以帮助初始化昂贵资源,但对于诸如 String 一类的简单对象,由于 lazy() 函数需要生成 LazyKProperty 这样的额外对象,反而会增加整个过程的开销。

Observable

Delegates.observable() 是另一个 Kotlin 标准库中内建的代理。观察者模式是一种设计模式,在这一模式中,一个对象会维护一个它的从属者的列表,这些从属者即被称为观察者。对象会在它自己的状态改变时对观察者进行通知。这一模式十分契合多个对象需要在某个值发生改变时得到通知的情况,可以避免实现为从属对象周期调用和检查资源是否更新。

observable() 函数接收两个参数: 初始化值与一个当值发生改变时会被调用的监听处理器。observable() 会创建一个 ObservableProperty 对象,用于在每次 setter 被调用时执行您传给代理的 lambda 表达式。

class Person {
var address: String by Delegates.observable(“not entered yet!”) {
property, oldValue, newValue ->
// 执行更新操作
}
}

通过观察反编译后的 Person 类型,我们可以看到 Kotlin 编译器生成了一个继承 ObservableProperty 的类。这个类同时也实现了一个叫做 afterChange() 的函数,这个函数持有您传递给 observable 代理的 lambda 函数。

protected void afterChange(@NotNull KProperty property, Object oldValue, Object newValue) {
// 执行更新操作
}

afterChange() 函数由父 ObservableProperty 类的 setter 调用,这意味着每当调用者为 address 设置一个新的值,setter 就会自动调用 afterChange() 函数,结果就会使所有的监听器都会收到有关改变的通知。

class Person {
var address: String by Delegates.observable(“not entered yet!”) {
property, oldValue, newValue ->
// 执行更新操作
}
}

您还可以从反编译后的代码中看到 beforeChange() 函数的调用,observable 代理不会使用 beforeChange()。但对于您接下来会看到的 vetoable(),这一函数却是功能实现的基础。

vetoable

vetoable() 是一个内建代理,属性将否决权委托给它的值。与 observable() 代理类似,vetoable() 同样接受两个参数: 初始值与监听器,当任何调用者想要修改属性值时,监听器就会被调用。

var address: String by Delegates.vetoable(“”) {
property, oldValue, newValue ->
newValue.length > 14
}

如果 lambda 表达式返回 true,属性值就会被修改,反之则保持不变。在本例中,如果调用者尝试使用长度小于 15 个字符的字符串来更新地址的话,当前值就不会发生改变。

观察反编译后的 Person 可以发现,Kotlin 新生成了一个继承 ObservableProperty 的类,该类中包含了我们传入 beforeChange() 函数的 lambda 表达式,setter 会在每次值被设置之前调用 lambda 表达式。

public final class Person s p e c i a l special specialinlined$vetoable$1 extends ObservableProperty {

protected boolean beforeChange(@NotNull KProperty property, Object oldValue, Object newValue) {
Intrinsics.checkParameterIsNotNull(property, “property”);
String newValue = (String)newValue;
String var10001 = (String)oldValue;
int var7 = false;
return newValue.length() > 14;
}
}

notNull

Kotlin 标准库中所提供的最后一个内建代理是 Delegates.notNull()notNull() 允许一个属性可以延后一段时间初始化,与 lateinit 类似。由于 notNull() 会为每个属性创建额外的对象,所以大多数情况下推荐使用 lateinit。不过,您可以将 notNull() 与原生类型一同使用,这点是 lateinit 所不支持的。

val fullname: String by Delegates.notNull()

notNull() 使用一种特殊类型的 ReadWriteProperty: NotNullVar。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐