我将根据Data的参数在DClass类中设置变量

abstract class Data(p: String) {
    var a1: String
    var a2: String

    init {
        """(\w+)(\d+)""".toRegex().find(p)!!.groupValues.run {
            a1 = "a1 is ${get(1)}"
            a2 = "a2 is ${get(2)}"
        }
    }
}

data class DClass(val p1: String, val p2: String) : Data(p1)

然后,在创建a1之后,我就能获得a2DClass的值:
DClass("string1", "string2").run { println("$a1 $a2") }

它应返回“a1是string a2是1

接下来,我尝试通过适当的JSON响应进行改造以初始化DClass:@GET("loadDClass") suspend fun dClass(): DClass
并说程序执行a1a2的相同输出,它只返回:

“a1是null a2是null”。

所以我发现init{}Data块被跳过了,因为改型只是建立DClass而没有进行初始化

是否可以在不手动进行的情况下初始化抽象类的变量?

最佳答案

不会调用init块,因为GsonConverterFactory(我假设您会使用它,因为在这种情况下它很常见)以一种不调用其构造函数的特殊方式构造了DClass。特别是,使用了一个称为UnsafeAllocator的内部类。该类的JavaDoc声明:

/**
 * Do sneaky things to allocate objects without invoking their constructors.
 * [...]
 */

您可以编写自己的Retrofit Converter.Factory,但这将使IMO显得过大。我建议您向DClass添加一个简单的成员函数,而不是从Data继承,并且还从abstract中删除Data关键字。 DClass应该看起来像这样:
data class DClass(val p1: String, val p2: String)
    fun newData(): Data = Data(p1)
}

那么您可以根据响应的Data构造一个body()实例:
call.execute().body()?.newData()?.run { println("$a1 $a2") }

关于object - 初始化时,翻新会跳过数据类的init {}块,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58260386/

10-10 02:04