Kotlin/JS嵌套内部类继承报错及运行结果异常问题
问题背景
以下多层嵌套inner类、跨层级内部类继承代码在Kotlin/JS环境运行时未得到预期结果"Inner2Outer2QualifiedCallsInner1Outer1QualifiedCalls":
- 次级构造函数实现版本直接抛出JS运行时异常:
Cannot read properties of undefined (reading 'name') - 改为主构造函数搭配init块的实现版本后,输出结果为
Outer2QualifiedCallsundefinedOuter2QualifiedCalls,不符合预期,且无法用公开的Kotlin构造执行顺序规则解释。
异常原因说明
两类异常均与构造代码执行顺序无关,根源是Kotlin/JS编译器对inner子类继承外部作用域inner父类时的隐式外部实例传递逻辑存在实现缺陷,具体逻辑如下:
- 规则基础:Kotlin的
inner类实例会隐式绑定对应外部类的实例引用。若inner子类继承定义在其他外部类下的inner父类,编译器需要自动给父类构造函数传递符合类型要求的外部实例。示例中Inner2继承定义在Outer1中的Inner1,Inner1要求绑定Outer1类型的外部实例,而Inner2自身绑定的Outer2实例是Outer1的子类,完全符合类型约束,该逻辑在Kotlin/JVM后端实现正确,运行结果符合预期。 - 次级构造版本抛错原因:Kotlin/JS编译
Inner2的super()调用逻辑时,未将当前实例绑定的Outer2引用传递给父类Inner1的构造函数,导致Inner1初始化阶段访问this@Outer1.name时,拿到的外部类引用为undefined,直接触发JS类型错误。 - 主构造+init块版本输出undefined原因:该写法触发编译器不同的初始化编译路径,未出现引用完全丢失的问题,但父类
Inner1构造执行时,持有的外部类引用、子类重写的name属性均未完成正确初始化绑定:父类构造访问this@Outer1.name时拿到未初始化的默认值undefined,转为字符串后拼入superResult,最终输出出现异常的undefined字段。
该问题属于Kotlin/JS的已知实现Bug,并非代码本身不符合Kotlin语法规范,相同代码在Kotlin/JVM环境运行可得到预期结果。
内容的提问来源于stack exchange,提问作者Molly Tian
相关产品推荐
相关产品推荐

