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

Kotlin调用私有构造器报Cannot access <init>的原因及<init>含义

<init>的具体指代

你在报错里看到的<init>不是Kotlin代码层面定义的方法名,是JVM字节码规范里定死的实例初始化方法的内部命名,所有跑在JVM上的语言(Kotlin、Java都算),类里写的每一个构造方法编译成字节码后,都会对应生成一个签名匹配的<init>方法:

  • 这个方法执行的时候,会按顺序完成类实例属性的初始赋值、初始化块里的逻辑运行、构造函数内写的自定义逻辑,最终把初始化完成的对象返回
  • 容易搞混的是同属字节码固定命名的<clinit>,这是类级别的静态初始化方法,负责处理伴生对象常量、静态代码块这类类加载阶段就会跑的逻辑,和实例创建没关系。
触发"Cannot access <init>"报错的根本原因

这个报错本质就是普通的私有成员访问权限不通过,结合代码场景拆解逻辑非常清晰:

  1. 你给Person的主构造加了private修饰符,编译后对应的<init>构造方法访问权限就被设为私有,按照Kotlin的访问规则,私有成员只允许在类自身的内部作用域调用。
    对应类代码:
class Person private constructor(val firstName:String , val lastName: String) {
    companion object {
        fun createPerson(firstName: String, lastName: String): Person {
            return Person(firstName, lastName)
        }
    }
}
  1. 伴生对象里的工厂方法createPerson能正常调用构造,是因为伴生对象本身就是Person类绑定的内部成员,天然持有外部类所有私有成员的访问权限,所以在这里调用私有构造完全合法:
// 合法调用,正常运行
val person1 = Person.createPerson("Niels", "Abel")
  1. 你在类外部直接写Person("Évariste", "Galois")的时候,本质是绕过公开的工厂方法,直接调用被标记为私有的<init>构造方法,编译器做权限校验时发现当前作用域没有访问私有成员的资格,就会抛出对应错误:
// 编译不通过,触发报错
val person2 = Person("Évariste", "Galois")

至于为什么报错里直接显示<init>而不是显示你写的constructor,只是因为编译器做检查时直接读了字节码层面的方法标识,没有额外做一层面向开发者的名称转换而已,没有什么特殊逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:03:20