You need to enable JavaScript to run this app. 在Hilt中如何在Kotlin类init代码块内调用已注入对象的方法
优惠活动
大模型
产品
解决方案
定价
更多

在Hilt中如何在Kotlin类init代码块内调用已注入对象的方法

你的崩溃原因确实是Hilt注入时序问题:字段注入的执行时机在构造函数、init代码块全部执行完毕之后,因此init块运行时@Inject标记的lateinit字段还未完成赋值,就会抛出未初始化异常。

以下是优先级从高到低的优雅实现方案:

方案1:优先改用构造函数注入(最推荐)

把依赖直接通过构造函数注入,这样构造执行时依赖已经完成赋值,init块可以直接正常调用,不需要依赖字段注入,同时也避免了lateinit的空安全风险,完全符合Dagger/Hilt的设计规范。
修改后的示例代码:

// 仅需修改Test2的注入方式即可
class Test2 @Inject constructor(
    // 将ITest1改为构造参数注入
    private val test1: ITest1
): ITest2 {

    override fun doSomethingElse() {
        println("Something else ")
    }

    // 此时init块可以正常访问test1
    init {
        test1.doSomething()
    }
}

方案2:使用@PostConstruct注解执行初始化

如果因为业务逻辑限制确实不能改用构造函数注入,可以用@PostConstruct注解标记初始化方法,Hilt会在所有字段注入完成后自动调用该方法,无需在Module中手动处理。
示例代码:

import javax.annotation.PostConstruct

class Test2 @Inject constructor(): ITest2 {

    @Inject
    lateinit var test1: ITest1

    override fun doSomethingElse() {
        println("Something else ")
    }

    // 去掉原init块,初始化逻辑移到被@PostConstruct标记的方法中
    @PostConstruct
    fun initAfterInject() {
        test1.doSomething()
    }
}

注意该方法必须是无参数的,且每个类只能有一个被@PostConstruct标记的方法。

方案3:自定义初始化方法(你当前的临时方案)

如果前两种方案都不满足需求,才推荐用手动调用初始化的方案,适合需要传入自定义初始化参数的特殊场景。

内容的提问来源于stack exchange,提问作者Ivan Škugor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 00:06:02