当前位置: 首页 > 知识库问答 >
问题:

如何安全地解决初始值设定项中的空检查?

商同化
2023-03-14

我正在写一个测试用例,我需要一些私有属性。由于这些私有数据是从私有方法生成的,所以我决定在计算完成后使用反射来检索它们。后来,我想起了委托的属性,并决定编写一个通用委托。以下是我目前得到的代码

fun <T> reflect(instance: Any, initOnce: Boolean = true) = ReflectBackedProperty<T>(initOnce, instance)

class ReflectBackedProperty<T>(val initOnce: Boolean, val instance: Any): ReadOnlyProperty<Any, T>  {
    var initialized = false
    lateinit var cache: T // <--- (a)
    override opertaor fun getValue(thisRef: Any, property: KProperty<*>): Any? {
        @Suppress("UNCHECKED_CAST")
        if (!initialized || !initOnce) {
            cache = instance.javaClass.getDeclaredField(property.name).get(instance) as T
            initialized = true
        }
        return cache
    }
}

Kthacks.java

public final class KTHacks {
    private KTHacks() {
        throw new UnsupportedOperationException();
    }

    /**
     * Forge a null into a platform type and take advantage of relaxed null-checks.
     * @param <T>
     * @return
     */
    public static <T> T NULL() {
        return null;
    }
}

ReflectBakedProperty.kt

import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

fun <T> reflect(instance: Any, initOnce: Boolean = true) = ReflectBackedProperty<T>(initOnce, instance)

class ReflectBackedProperty<T>(val initOnce: Boolean, val instance: Any): ReadOnlyProperty<Any, T> {
    var initialized = false
    var cache: T = KTHacks.NULL()
    override operator fun getValue(thisRef: Any, property: KProperty<*>): T {
        @Suppress("UNCHECKED_CAST")
        if (!initialized || !initOnce) {
            cache = instance.javaClass.getDeclaredField(property.name).get(instance) as T
            initialized = true
        }
        return cache
    }
}

共有1个答案

尹赞
2023-03-14

一种方法是将t限制为仅允许具有上限的不可空类型:

class ReflectBackedProperty<T: Any> : ReadOnlyProperty<Any, T> {}

另一种方法是根本不需要使用lateinit

class ReflectBackedProperty<T>(val initOnce: Boolean, val instance: Any): ReadOnlyProperty<Any, T>  {
    var initialized = false
    var cache: T? = null

    override operator fun getValue(thisRef: Any, property: KProperty<*>): T {
        if (!initialized || !initOnce) {
            cache = instance.javaClass.getDeclaredField(property.name).get(instance) as T
            initialized = true
        }
        return cache as T
    }
}
 类似资料:
  • 我通过解决一些黑客等级问题来学习java。下面的代码是关于学习静态初始值设定项块的。例外情况是thown和Capture,但程序仍在运行,我不确定原因。 输入:-1,2 预期输出:java.lang.例外:宽度和高度必须为正 实际输出:宽度和高度必须为正-2

  • 我对Swift类有一个问题。我有UITableViewController类和UITableViewCell类的swift文件。我的问题是UITableViewCell类和网点。这个类有一个错误Class“HomeCell”没有初始化程序,我不明白这个问题。 感谢您的回复。

  • 本文向大家介绍详解C#中使用对象或集合的初始值设定项初始化的操作,包括了详解C#中使用对象或集合的初始值设定项初始化的操作的使用技巧和注意事项,需要的朋友参考一下 使用对象初始值设定项初始化对象 可以使用对象初始值设定项以声明方式初始化类型对象,而无需显式调用类型的构造函数。 下面的示例演示如何将对象初始值设定项用于命名对象。编译器通过先访问默认实例构造函数然后处理成员初始化处理对象初始值设定项。

  • 我有一个这样的类,除了有多个成员: 我基本上希望对其进行聚合初始化,如下所示: 但由于自定义构造函数的原因,这似乎是不可能的,因此我想使用构造函数参数来模拟它: 这看起来有很多冗余,只是为了在可能的情况下移动和复制,尤其是在成员数量激增的情况下。我想我想要完美的转发? 但是现在我不能像这样使用空的初始化列表调用它: 因为无法推导出初始化列表参数类型。有没有不需要我写的解决方案 ?

  • 如果您可以在列表中执行此操作 你怎么能在字典里做同样的事情呢?

  • 我的 centos7 虚拟机中安装的 wiki.js + postgresql 运行初始化页面时出现下面提示,要如何解决