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

Kotlin如何修改构造函数JVM签名以解决平台声明冲突问题

错误原因

你遇到的签名冲突是JVM泛型擦除导致的:List<WebMenuItem>、List<Child>、List<ChildX>、List<ChildXX>这四个带泛型的参数,在编译后泛型类型会被擦除,全部变成List类型,导致四个构造函数编译后的JVM签名完全一致,JVM无法区分不同的构造函数。

解决方案

Kotlin不允许直接给构造函数添加@JvmName注解修改签名,推荐通过伴生对象工厂方法+@JvmName的方式解决冲突,修改后的RowModel代码如下:

class RowModel private constructor(
    @RowType var type: Int,
    var isExpanded: Boolean = false
) {
    companion object{
        @IntDef(WEB_MENU, CHILD, CHILDX, CHILDXX)
        @Retention(AnnotationRetention.SOURCE)
        annotation class RowType

        const val WEB_MENU = 1
        const val CHILD = 2
        const val CHILDX = 3
        const val CHILDXX = 4
        
        // 每个工厂方法添加唯一的@JvmName区分JVM签名
        @JvmName("createWithWebMenuItem")
        operator fun invoke(
            @RowType type: Int,
            webMenuItem: List<WebMenuItem>,
            isExpanded: Boolean = false
        ): RowModel {
            return RowModel(type, isExpanded).apply {
                this.webMenuItem = webMenuItem
            }
        }
        
        @JvmName("createWithChild")
        operator fun invoke(
            @RowType type: Int,
            child: List<Child>,
            isExpanded: Boolean = false
        ): RowModel {
            return RowModel(type, isExpanded).apply {
                this.child = child
            }
        }
        
        @JvmName("createWithChildX")
        operator fun invoke(
            @RowType type: Int,
            childX: List<ChildX>,
            isExpanded: Boolean = false
        ): RowModel {
            return RowModel(type, isExpanded).apply {
                this.childX = childX
            }
        }
        
        @JvmName("createWithChildXX")
        operator fun invoke(
            @RowType type: Int,
            childXX: List<ChildXX>,
            isExpanded: Boolean = false
        ): RowModel {
            return RowModel(type, isExpanded).apply {
                this.childXX = childXX
            }
        }
    }
    
    lateinit var webMenuItem : List<WebMenuItem>
    lateinit var child: List<Child>
    lateinit var childX: List<ChildX>
    lateinit var childXX: List<ChildXX>
}

修改后使用方式和原来的构造函数调用完全一致,不需要改其他地方的调用代码:

// 和之前调用构造函数的写法完全相同
val rowModel = RowModel(RowModel.WEB_MENU, menuList)

替代方案(可选)

如果你不想用工厂方法,也可以给每个构造函数加一个无意义的占位参数区分签名,不过可读性较差,不推荐:

constructor (@RowType type : Int, webMenuItem: List<WebMenuItem>, isExpanded : Boolean = false, placeholder: Int = 0){
    this.type = type
    this.webMenuItem = webMenuItem
    this.isExpanded = isExpanded
}
constructor(@RowType type : Int, child: List<Child>, isExpanded : Boolean = false, placeholder: String = ""){
    this.type = type
    this.child = child
    this.isExpanded = isExpanded
}
// 剩余两个构造函数同理添加不同默认值的占位参数即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:15:03