Модификация пропускает блок init {} класса данных при инициализации - PullRequest
1 голос
/ 06 октября 2019

Я собираюсь установить переменные в классе 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 is string a2 is 1», как и должно быть

Далее я пытаюсь сделать модифицированную инициализацию DClass из правильногоJSON-ответ: @GET("loadDClass") suspend fun dClass(): DClass

и сказать, что программа должна выполнить тот же вывод a1 и a2, он просто возвращает:

"a1 равно null a2 равно null ".

Итак, я обнаружил, что блок init{} из Data пропущен, так как модернизация только строит DClass, но не выполняет инициализацию

Можно ли сделатьпеременные абстрактного класса инициализируются, не делая это вручную?

1 Ответ

0 голосов
/ 07 октября 2019

Блок 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") }
...