栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Kotlin: 何时使用自定义访问器getter

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Kotlin: 何时使用自定义访问器getter

记一个有意思的问题,在国外发现了一个帖子,为了避免有时候看不到,这里将原文复制如下:

Kotlin Demystified: When to use custom accessors

While working on UAMP, I found it convenient to wrap several support library classes in a helper for a variety of reasons. One of the features I wanted from this wrapper was the ability to quickly reference the “transport controls” class, which is used to give commands such as play and pause.
To make it convenient, I added a property to my wrapper:

val transportControls: MediaControllerCompat.TransportControls
    = mediaController.transportControls

The thing to keep in mind is that mediaController is a lateinit var, because it’s created during a callback to a service connection. Thus this code crashes immediately when the app is run:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android.uamp.next, PID: 18641
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.uamp.next/com.example.android.uamp.MainActivity}:
    kotlin.UninitializedPropertyAccessException: lateinit property mediaController has not been initialized

The fix is to add a custom accessor to this property:

val transportControls: MediaControllerCompat.TransportControls
    get() = mediaController.transportControls

But why?
The easiest way to understand what’s going on is to look at the bytecode for the two variations. Doing this in Android Studio is as easy as Tools > Kotlin > Show Kotlin Bytecode. Then select the Decompile button to look at the equivalent Java code.
Without get():

@NotNull
private final TransportControls transportControls = mediaController.getTransportControls();
@NotNull
public final TransportControls getTransportControls() {
    return this.transportControls;
}

With get():

@NotNull
public final TransportControls getTransportControls() {
    return mediaController.getTransportControls();
}

In the first case, a member variable transportControls was being set when the class was constructed. In the second, it actually calls mediaController.getTransportControls() every time the transportControls property is accessed.
In my case, this is exactly what I wanted to do. I don’t want to save the object returned from mediaController.getTransportControls() in my object, I just want to make it more convenient to write that code. Because of this, the code should be val transportControls get() = ....
This isn’t always the right approach, however. Take this code for example:

val ticket get() = findTicketInDb()

Yikes! Each time ticket is accessed, the code will search the database for the ticket! That’s probably not what we want. In this case the right approach would be to write:

val ticket = findTicketInDb()

This will call findTicketInDb() once, when the object is created, and return that same value each time the property ticket is accessed.
Kotlin properties can be deceptively simple. Understanding the difference between properties computed once when the object is created, and those with custom get() methods, which are computed each time the property is accessed, can mean the difference between writing clear code and introducing unintended behavior into your app.
Be sure to follow the Android Developers publication for more great content, and stay tuned for more articles on Kotlin!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/685044.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号