可待因中的 NullPointerException
NullPointerException inside Kodein
我正在用 Kodein 试用 Kotlin,在我当前的项目中,我在 Kodein 中得到了一个 NPE,但我不知道为什么。
我有一些数据 classes 和匹配的存储库提供了它们的列表:
data class Cat(val name: String)
data class Dog(val name: String)
interface Repository<T> {
val all: List<T>
}
interface CatRepository : Repository<Cat>
interface DogRepository : Repository<Dog>
这些存储库的实现目前由大师支持 class:
data class AnimalData(val cats: List<Cat>, val dogs: List<Dog>)
我为存储库创建了一个抽象基础 class:
abstract class AnimalDataRepository<T>(override val kodein: Kodein) : Repository<T>, KodeinAware {
private val animalData: AnimalData by instance()
abstract val property: (AnimalData) -> List<T>
override val all: List<T> = animalData.let(property)
}
因此存储库实现如下所示:
class CatRepositoryImpl(override val kodein: Kodein) : CatRepository, AnimalDataRepository<Cat>(kodein) {
override val property = AnimalData::cats
}
正在设置并 运行:
fun main() {
val kodein = Kodein {
bind<AnimalData>() with singleton { AnimalData(listOf(Cat("Tigger")), listOf(Dog("Rover"))) }
bind<CatRepository>() with singleton { CatRepositoryImpl(kodein) }
}
val catRepository: CatRepository by kodein.instance()
println(catRepository.all)
}
导致 Kotlin 内部出现 NPE:
Exception in thread "main" java.lang.NullPointerException
at org.kodein.di.KodeinAwareKt$Instance.invoke(KodeinAware.kt:176)
at org.kodein.di.KodeinAwareKt$Instance.invoke(KodeinAware.kt)
at org.kodein.di.KodeinProperty$provideDelegate.invoke(properties.kt:42)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at AnimalDataRepository.getAnimalData(KodeinExample.kt)
at AnimalDataRepository.<init>(KodeinExample.kt:27)
at CatRepositoryImpl.<init>(KodeinExample.kt:30)
at KodeinExampleKt$main$kodein.invoke(KodeinExample.kt:40)
at KodeinExampleKt$main$kodein.invoke(KodeinExample.kt)
at org.kodein.di.bindings.Singleton$getFactory.invoke(standardBindings.kt:130)
...
我不清楚为什么会这样。它与 AnimalDataRepository
中 "property" 映射 lamba 的使用有关,因为当我不使用它时它工作正常。
作为要点的完整代码:https://gist.github.com/RoToRa/65d664d2d7497ddbf851a1be019f631d
这是因为在您的 class AnimalDataRepository
中您定义了:
override val all: List<T> = animalData.let(property)
虽然Kodein是懒惰工作的,因此之前定义了all
,这就是为什么animalData
是空的。但是,您可以通过以下方式解决此问题:
override val all: List<T> by lazy { animalData.let(property) }
我正在用 Kodein 试用 Kotlin,在我当前的项目中,我在 Kodein 中得到了一个 NPE,但我不知道为什么。
我有一些数据 classes 和匹配的存储库提供了它们的列表:
data class Cat(val name: String)
data class Dog(val name: String)
interface Repository<T> {
val all: List<T>
}
interface CatRepository : Repository<Cat>
interface DogRepository : Repository<Dog>
这些存储库的实现目前由大师支持 class:
data class AnimalData(val cats: List<Cat>, val dogs: List<Dog>)
我为存储库创建了一个抽象基础 class:
abstract class AnimalDataRepository<T>(override val kodein: Kodein) : Repository<T>, KodeinAware {
private val animalData: AnimalData by instance()
abstract val property: (AnimalData) -> List<T>
override val all: List<T> = animalData.let(property)
}
因此存储库实现如下所示:
class CatRepositoryImpl(override val kodein: Kodein) : CatRepository, AnimalDataRepository<Cat>(kodein) {
override val property = AnimalData::cats
}
正在设置并 运行:
fun main() {
val kodein = Kodein {
bind<AnimalData>() with singleton { AnimalData(listOf(Cat("Tigger")), listOf(Dog("Rover"))) }
bind<CatRepository>() with singleton { CatRepositoryImpl(kodein) }
}
val catRepository: CatRepository by kodein.instance()
println(catRepository.all)
}
导致 Kotlin 内部出现 NPE:
Exception in thread "main" java.lang.NullPointerException
at org.kodein.di.KodeinAwareKt$Instance.invoke(KodeinAware.kt:176)
at org.kodein.di.KodeinAwareKt$Instance.invoke(KodeinAware.kt)
at org.kodein.di.KodeinProperty$provideDelegate.invoke(properties.kt:42)
at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
at AnimalDataRepository.getAnimalData(KodeinExample.kt)
at AnimalDataRepository.<init>(KodeinExample.kt:27)
at CatRepositoryImpl.<init>(KodeinExample.kt:30)
at KodeinExampleKt$main$kodein.invoke(KodeinExample.kt:40)
at KodeinExampleKt$main$kodein.invoke(KodeinExample.kt)
at org.kodein.di.bindings.Singleton$getFactory.invoke(standardBindings.kt:130)
...
我不清楚为什么会这样。它与 AnimalDataRepository
中 "property" 映射 lamba 的使用有关,因为当我不使用它时它工作正常。
作为要点的完整代码:https://gist.github.com/RoToRa/65d664d2d7497ddbf851a1be019f631d
这是因为在您的 class AnimalDataRepository
中您定义了:
override val all: List<T> = animalData.let(property)
虽然Kodein是懒惰工作的,因此之前定义了all
,这就是为什么animalData
是空的。但是,您可以通过以下方式解决此问题:
override val all: List<T> by lazy { animalData.let(property) }