Плагин компилятора Kotlin no-arg используется для создания конструктора без аргументов, даже если они требуются классу.
Это очень полезно при работе с сериализацией и десериализацией, например при чтении значения из DynamoDB Amazon.
Делегат lazy
— это часто используемая функция языка, однако я не могу заставить ее работать с плагином без аргументов.
@NoArg
data class Foo(val a: String, val b: String) {
val delegated by lazy { a + b }
}
val foo = getFooViaReflection() // The deserialization that will use the no-arg constructor
При доступе к foo.delegated
будет выдано исключение NullPointerException. При дальнейшем осмотре я обнаружил, что поле делегата никогда не инициализируется и, следовательно, при доступе к нему имеет значение null, что приводит к нулевому указателю.
Как обойти это?
Такое поведение несколько ожидаемо, и вопрос по этому поводу был открыт еще в 2016 году.
Чтобы обойти это, вы должны настроить подключаемый модуль без аргументов для вызова инициализаторов (будет создан ленивый делегат), для которого по умолчанию установлено значение false.
// build.gradle
noArg {
invokeInitializers = true
}
// build.gradle.kts
configure<NoArgExtension> {
invokeInitializers = true
}