我将根据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
之后,我就能获得a2
和DClass
的值:DClass("string1", "string2").run { println("$a1 $a2") }
它应返回“a1是
string
a2是1
”接下来,我尝试通过适当的JSON响应进行改造以初始化DClass:
@GET("loadDClass") suspend fun dClass(): DClass
并说程序执行
a1
和a2
的相同输出,它只返回:“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/