Kotlin实现适配器模式时出现getter方法getRadius重复命名报错问题
异常信息
Exception in thread "main" java.lang.ClassFormatError: Duplicate method name "getRadius" with signature "()I" in class file RoundHole at java.lang.ClassLoader.defineClass1 (ClassLoader.java:-2) at java.lang.ClassLoader.defineClass (ClassLoader.java:756) at java.security.SecureClassLoader.defineClass (SecureClassLoader.java:142)
错误原因
Kotlin 为主构造函数中声明的val属性默认生成与属性名对应的getter方法,你在实现WorkingWithRound接口的RoundPeg、RoundHole类中,同时存在两种getRadius()的实现:
- 主构造参数
val radius自动生成的getRadius() - 手动重写的
override fun getRadius() = radius
两个方法签名完全一致,JVM加载类时检测到重复方法触发报错。
修复方案
提供两种可直接运行的改法:
改法1:适配Kotlin语法习惯,用属性实现接口
interface WorkingWithRound { val radius: Int } open class RoundPeg(override val radius: Int = 0): WorkingWithRound class RoundHole(override val radius: Int = 0): WorkingWithRound { fun fit(peg: RoundPeg) { println(radius >= peg.radius) } } class SquarePeg(val width: Int = 0) class SquarePegAdapter(val speg: SquarePeg): RoundPeg() { override val radius: Int get() = (speg.width / 2 * 1.4).toInt() } fun main() { val hole = RoundHole(5) val rpeg = RoundPeg(5) hole.fit(rpeg) // 输出true val small_sqpeg = SquarePeg(5) val large_sqpeg = SquarePeg(10) val small_sqpeg_adapter = SquarePegAdapter(small_sqpeg) val large_sqpeg_adapter = SquarePegAdapter(large_sqpeg) hole.fit(small_sqpeg_adapter) // 输出true hole.fit(large_sqpeg_adapter) // 输出false }
改法2:不修改原有接口定义,规避自动生成getter冲突
interface WorkingWithRound { fun getRadius(): Int } // 主构造参数加private,避免自动生成public的getRadius方法 open class RoundPeg(private val radius: Int = 0): WorkingWithRound { override fun getRadius() = radius } // 主构造参数加private class RoundHole(private val radius: Int = 0): WorkingWithRound { override fun getRadius() = radius fun fit(peg: RoundPeg) { println(getRadius() >= peg.getRadius()) } } class SquarePeg(val width: Int = 0) class SquarePegAdapter(val speg: SquarePeg): RoundPeg() { override fun getRadius() = (speg.width / 2 * 1.4).toInt() } fun main() { val hole = RoundHole(5) val rpeg = RoundPeg(5) hole.fit(rpeg) val small_sqpeg = SquarePeg(5) val large_sqpeg = SquarePeg(10) val small_sqpeg_adapter = SquarePegAdapter(small_sqpeg) val large_sqpeg_adapter = SquarePegAdapter(large_sqpeg) hole.fit(small_sqpeg_adapter) hole.fit(large_sqpeg_adapter) }
内容的提问来源于stack exchange,提问作者Nero Nguyen
相关产品推荐
相关产品推荐

