如何编写Kotlin数据类使注解编译为对应Java字节码?
解决方案
要让Kotlin数据类生成与目标Java类一致的字节码(包含Getter返回类型及类型参数的@NonNull注解),需要结合正确的注解写法和Kotlin编译选项:
1. 核心问题分析
你遇到的编译错误,是因为@get:这个使用站点目标仅适用于Getter方法本身,无法直接应用到类型或类型参数上。而@NonNull注解支持TYPE_USE目标(用于标注类型位置),但Kotlin默认不会将这类类型注解编译到Java字节码中,仅会保留在Kotlin的@kotlin.Metadata元数据里,无法被Java库识别。
2. 正确代码写法
方案A:生成完整的三个注解(方法、返回类型、类型参数)
如果需要和目标Java类完全一致的字节码(包含方法上的@NonNull),使用以下写法:
data class Pet(@get:NonNull val names: List<@NonNull String>)
方案B:仅保留返回类型和类型参数的注解(满足最低要求)
如果只需要字节码中的返回类型及类型参数的@NonNull注解,可以简化为:
data class Pet(val names: List<@NonNull String>)
3. 开启编译选项
关键是要开启Kotlin的-Xemit-jvm-type-annotations编译选项,让Kotlin将类型注解编译到Java字节码中(默认不开启)。同时需要指定JVM目标版本为1.8及以上(因为TYPE_USE是Java 8引入的特性)。
Gradle配置(build.gradle.kts)
tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs += "-Xemit-jvm-type-annotations" jvmTarget = "1.8" } }
Maven配置(pom.xml)
<plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <args> <arg>-Xemit-jvm-type-annotations</arg> <arg>-jvm-target=1.8</arg> </args> </configuration> </execution> </executions> </plugin>
4. 验证结果
开启编译选项后,编译生成的字节码会:
- 对于方案A:Getter方法上有
@NonNull,返回类型(List)上有@NonNull,返回类型参数(String)上也有@NonNull,完全匹配目标Java类的字节码。 - 对于方案B:仅返回类型和类型参数上有
@NonNull,满足你提出的最低要求。
内容的提问来源于stack exchange,提问作者Acanda
相关产品推荐
相关产品推荐

