You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin Data Class中使用@Value注解?解决未初始化报错

问题分析与解决

你遇到的lateinit property personOne has not been initialized错误,核心原因是Spring还没完成personOne的属性注入,就被Person类的次构造器调用了,或者持有personOne的类根本不是Spring管理的Bean,导致@Value注解完全没生效。

具体原因拆解

  • @Value是Spring的依赖注入注解,只有当变量所在的类被Spring容器管理(比如加了@Component、@Service等注解),Spring才会在Bean初始化阶段给personOne赋值。
  • 如果直接通过Person(20)这种方式实例化Person类,此时要么持有personOne的类还没被Spring初始化,要么这个类根本不是Bean,personOne自然还没被赋值,调用就会报错。

解决方案

方案1:让持有personOne的类成为Spring Bean,并通过Spring获取Person实例

首先给持有personOne的类加上Spring组件注解,比如@Component:

@Component
class SomeBean {
    @Value("\${person-one-name}")
    lateinit var personOne: String

    fun createPerson(age: Int): Person {
        return Person(personOne, age)
    }
}

然后在需要创建Person的地方,注入SomeBean并调用方法,而不是直接调用Person的次构造器:

@Service
class PersonService(private val someBean: SomeBean) {
    fun getPerson() {
        val person = someBean.createPerson(25)
        // 使用person
    }
}

方案2:将Person类纳入Spring管理,通过构造注入传递配置值

如果Person需要Spring管理,可以直接把配置值注入到Person的构造器:

@Component
data class Person(
    @Value("\${person-one-name}") val name: String,
    val age: Int
)

如果需要动态指定年龄,可以通过配置类创建实例:

@Configuration
class PersonConfig {
    @Value("\${person-one-name}")
    lateinit var personOneName: String

    @Bean
    fun createPerson(@Value("\${person-age}") age: Int): Person {
        return Person(personOneName, age)
    }
}

方案3:避免依赖全局变量,直接传递参数

最稳妥的方式是不让Person依赖外部全局变量,创建时直接传入name:

@Component
class SomeBean {
    @Value("\${person-one-name}")
    lateinit var personOne: String

    fun getPerson(age: Int): Person {
        return Person(personOne, age)
    }
}

这样只要调用getPerson时personOne已经完成注入,就不会出现初始化错误。

关键注意点

  • 不要在类的构造器(包括次构造器)中依赖Spring注入的lateinit变量,因为构造器执行时Spring的注入逻辑尚未完成。
  • 只有Spring管理的Bean,@Value注解才会生效,普通类中的@Value不会被Spring处理。

内容的提问来源于stack exchange,提问作者Hamza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:45:32