kotlin 字段 foo 和 isFoo 冲突:以下声明具有相同的 JVM 签名
Posted
技术标签:
【中文标题】kotlin 字段 foo 和 isFoo 冲突:以下声明具有相同的 JVM 签名【英文标题】:kotlin field foo and isFoo ***: The following declarations have the same JVM signature 【发布时间】:2021-08-14 07:16:11 【问题描述】:data class Bar(
var foo: String = "",
var isFoo: String = ""
)
编译器报错:
平台声明冲突:以下声明具有相同的 JVM 签名 (setFoo(Ljava/lang/String;)V):
public final fun (
如何提示编译器为 setter 使用原始字段名称? (setFoo 和 setIsFoo) 注意:代码是由jooq生成的(来自数据库模式),所以手动更改代码不是一个好方法
【问题讨论】:
在不修改代码的情况下没有任何方法可以做到这一点。这不是您可以通过编译器设置更改的内容。 通常情况下,您可以使用@JvmName
执行此操作,但这需要修改代码。我想说这是代码生成器中的一个错误/疏忽——它应该尽量不生成无效的代码。
我想修改代码,因此它设置 jvm 名称不应该引起任何问题,因此是一个有效的答案 - 即使它的修改代码。
【参考方案1】:
你需要用@JvmName
注解setter:
data class BarFoo(
var foo: String = "",
@set:JvmName("setIsFoo") var isFoo: String = ""
)
没有编译器错误,而是记录在案的行为(请参阅https://kotlinlang.org/docs/java-to-kotlin-interop.html#properties),要在不修改代码的情况下对其进行调整,您必须编写一些编译器插件。
也许有办法让jooq生成这样的代码?
【讨论】:
感谢您记录解决方案。我们很快就会在 jOOQ 代码生成器中支持这个 OOTB:github.com/jOOQ/jOOQ/issues/11912【参考方案2】:这是 jOOQ 的代码生成器中的一个错误,它应该为这种情况生成 @set:JvmName
注释,正如 Михаил Нафталь 所建议的那样。错误编号为#11912,已针对 3.15.0 和 3.14.12 修复。
您可以通过重写 KotlinGenerator.generatePojo()
方法(需要复制整个代码并修补相关位)或使用 hack 来解决此问题:您可以重写 KotlinGenerator.printColumnJPAAnnotation()
方法并在那里实现您的逻辑:
// Example implemented in Java:
@Override
protected void printColumnJPAAnnotation(JavaWriter out, ColumnDefinition column)
super.printColumnJPAAnnotation(out, column);
String member = getStrategy().getJavaMemberName(column, Mode.POJO);
if (member.startsWith("is") && ((ColumnDefinition) column)
.getContainer()
.getColumns()
.stream()
.anyMatch(c -> member.equals("is" +
StringUtils.toUC(getStrategy().getJavaMemberName(c, Mode.POJO))
)))
out.println("@set:JvmName(\"%s\")",
getStrategy().getJavaSetterName(column, Mode.POJO));
【讨论】:
以上是关于kotlin 字段 foo 和 isFoo 冲突:以下声明具有相同的 JVM 签名的主要内容,如果未能解决你的问题,请参考以下文章