V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanck0605
V2EX  ›  Kotlin

Kotlin 如何检测所有 lateinit 的 field 是否初始化

  •  
  •   fanck0605 · 2020-07-07 23:49:06 +08:00 · 2417 次点击
    这是一个创建于 511 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 java 里,我一般用反射遍历所有 Field,并查看是否为 null

    Example example = new Example();
    
    // 这里解析一些文本并给 example 的成员变量赋值
    // do something...
    
    // 检测是否所有变量都被初始化
    Field[] fields = Example.class.getFields()
    for (Field field : fields) {
        try {
        	Object o = field.get(example);
            if (o == null) {
                throw new Exception();
            }
        } catch (IllegalAccessException ignored) {
        }
    }
    

    kotlin 代码中,所有成员变量都用了 lateinit 修饰符, 那有没有类似的方法可以,检测所有变量是否被 initialized

    6 条回复    2020-07-08 13:27:07 +08:00
    holmesabc
        1
    holmesabc   2020-07-08 00:00:08 +08:00
    this::wtf.isInitialized ??
    dcalsky
        2
    dcalsky   2020-07-08 00:06:51 +08:00
    `isInitialized`

    给你写了一段,看图~

    https://sm.ms/image/P5VSfbmoh7XrJFg
    aabbcc112233
        3
    aabbcc112233   2020-07-08 00:14:41 +08:00
    @holmesabc
    @dcalsky 审题,问的是判断所有变量。

    回复楼主:
    lateinit 的用法是很确定这个变量会在使用前被初始化。
    如果不确定,你应该使用可空类型来达到安全调用
    john6lq
        4
    john6lq   2020-07-08 08:46:36 +08:00 via iPhone
    @aabbcc112233 那就拿楼上方法遍历啊,你才是没“审题”的那个好吧,人家有这个需求你告诉他直接砍了而不是找解决办法。
    flywith24
        5
    flywith24   2020-07-08 09:20:08 +08:00
    为 Example 写个扩展函数,里面判断所有属性是否初始化,不知道是否满足你的需求
    fanck0605
        6
    fanck0605   2020-07-08 13:27:07 +08:00
    我也是刚写 Kotlin,比较看中 Kotlin 的对空值的处理,还有协程。

    @aabbcc112233
    如果使用了可空类型,那么以后的调用都要加 `!!`,虽然可以从代码层面控制这些 成员变量 非空,但是这似乎让代码变得不够优雅了。

    @holmesabc @dcalsky
    这么写的确可以判断单个 成员变量 ,编译时,成员变量 也是固定的,一个一个判断也不是不可以。
    但成员变量很多时,写出来的代码似乎就会很冗长。


    现在我是这么写的,不知道有没有优化的余地。
    ```
    class Car {

    lateinit var field1: String
    lateinit var field2: String
    lateinit var field3: String
    lateinit var name: String
    lateinit var color: String

    // 这里还有很多成员变量

    companion object {
    val memberProperties = Car::class.memberProperties

    fun parse(text : String): Car {

    val car = Car()

    // 这里解析一些文本,并初始化 car 的成员变量
    // var car.field1 = xxx
    // var car.field2 = xxx
    // var car.field3 = xxx


    // 检测是否都被初始化
    for (memberProperty in memberProperties) {
    try {
    memberProperty.get(car)
    } catch (e: UninitializedPropertyAccessException) {
    // 抛出异常,保证外部获得的对象,所有变量都被 initialized
    throw Exception("${memberProperty.name} is uninitialized! Failed to parse text: $text")
    }
    }
    return car
    }
    }
    }
    ```
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1236 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 18:40 · PVG 02:40 · LAX 10:40 · JFK 13:40
    ♥ Do have faith in what you're doing.