引入Kotlin编写的实体共享库时参数默认值丢失如何解决?
Kotlin 的构造参数默认值是 Kotlin 编译器专属特性,默认不会生成 Java 可识别的重载构造方法。你反编译看到的只有全参数构造,跨模块/Java 调用时自然要求传入所有参数,默认值逻辑默认只会在 Kotlin 同模块编译时由编译器处理。
方案1:使用 @JvmOverloads 注解(推荐,原生Kotlin特性,无额外依赖)
给实体类的主构造函数添加 @JvmOverloads 注解,Kotlin 编译器会自动为带默认值的参数逐级生成对应重载构造,Java 和跨模块 Kotlin 调用都能识别这些重载,直接使用默认值。
注意你原代码里 author 参数没有配置默认值,需要先补上默认值 null 才能在构造时省略该参数。
修改后的代码如下:
@Entity class Attachment @JvmOverloads constructor( @Id @GeneratedValue var id: Long? = null, var url: String? = "", @OneToOne var author: UserInfo? = null, // 补上默认值 var fileSize: Long? = 0, var fileName: String? = "", @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime") var createdAt: DateTime? = DateTime.now() )
注意:发布类库到Maven时不要自定义过滤掉
META-INF/*.kotlin_module文件,这些是Kotlin的元数据文件,跨模块Kotlin调用默认值需要依赖这些元数据,默认的maven-publish配置都会自动保留无需额外调整。
方案2:配合JPA场景配置Kotlin插件
如果你的类库是专门给JPA项目使用,还可以在类库的构建配置中添加 Kotlin JPA 插件,插件会自动给所有标注了 @Entity 的类生成无参构造,同时自动开放类和成员属性,避免JPA动态代理相关的问题。
Gradle 配置示例(build.gradle.kts):
plugins { kotlin("jvm") version "你的Kotlin版本号" kotlin("plugin.jpa") version "你的Kotlin版本号" }
如果有需要生成全参构造的场景,可以额外添加 kotlin-plugin-allopen 插件,配合 Lombok 的 @AllArgsConstructor 注解使用即可。
重新打包发布类库后,反编译新的类文件就能看到多个重载的构造方法,此时引入类库的项目就可以直接调用省略了默认值参数的构造方法。
内容的提问来源于stack exchange,提问作者xetra11

