我将基于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{}
的{{1}}块被跳过了,因为改型仅生成Data
而未进行初始化
是否可以在不手动进行的情况下初始化抽象类的变量?
答案 0 :(得分:0)
之所以没有调用init
块是因为GsonConverterFactory
(我假设您会使用它,因为在这种情况下它很常见)以一种特殊的方式构造了DClass
而不调用它构造函数。特别是,使用了一个名为UnsafeAllocator的内部类。该类的JavaDoc指出:
/**
* Do sneaky things to allocate objects without invoking their constructors.
* [...]
*/
您可以编写自己的翻新版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") }