深入解析:Kotlin 中companion object {} 什么时候触发

news/2025/10/7 19:18:00/文章来源:https://www.cnblogs.com/yxysuanfa/p/19128780

在 Kotlin 中,companion object 的初始化触发时机是一个重要但容易被忽视的细节。以下是详细的解释:

1. 基本触发时机

companion object 的初始化发生在:

  • 首次访问该类时(无论是访问伴生对象成员、创建类实例,还是通过反射访问类)

  • 类似于 Java 的静态初始化块,但更灵活

  • class MyClass {
    companion object {
    init {
    println("Companion object 初始化!")
    }
    val CONST = "Hello"
    }
    }fun main() {
    println("程序启动")
    MyClass.CONST // 第一次访问 MyClass 时触发初始化
    }

 输出

程序启动
Companion object 初始化!

2. 具体触发场景

以下操作都会触发 companion object 初始化:

(1) 直接访问伴生对象成员

MyClass.CONST          // 触发
MyClass.Companion      // 触发

(2) 创建类实例

val obj = MyClass()    // 触发

(3) 通过反射访问类

MyClass::class          // 触发(Kotlin 反射)

(4) 访问类的其他声明

MyClass::class          // 触发(Kotlin 反射)

3. 不会触发的情况

以下操作不会触发初始化:

// 仅声明类型(未实际访问)
val clazz: Class = MyClass::class.java// 作为类型参数(未实例化或访问)
fun process(clazz: Class<*>) {}
process(MyClass::class.java) // 不会触发

4. 与 Java 静态初始化的对比

特性Kotlin companion objectJava static 块
初始化时机首次访问类时类加载时
懒加载是(按需初始化)否(类加载时强制初始化)
线程安全是(JVM 保证)

5. 实际应用中的注意事项

(1) 性能优化
class HeavyInitialization {
companion object {
val HEAVY_RESOURCE = loadResource() // 避免在伴生对象中放重型初始化
}
}// 改为懒加载
class BetterApproach {
companion object {
val heavyResource by lazy { loadResource() }
}
}
(2) 循环依赖问题
class A {
companion object {
val VALUE = B.VALUE // 如果 B 的伴生对象也依赖 A,会导致栈溢出
}
}class B {
companion object {
val VALUE = A.VALUE
}
}

解决方案:使用 lazy 延迟初始化

class A {
companion object {
val VALUE by lazy { B.VALUE }
}
}

6. 验证示例

class Test {
companion object {
init { println("伴生对象初始化") }
}init { println("类实例初始化") }
}fun main() {
println("阶段1")
Test::class // 仅访问 KClass,不触发println("阶段2")
Test.Companion // 触发初始化println("阶段3")
Test() // 伴生对象已初始化,不会再次触发
}

输出

阶段1
阶段2
伴生对象初始化
阶段3
类实例初始化

总结

  • companion object 在首次真正使用类时初始化(懒加载)
  • 比 Java 的静态初始化更灵活,但逻辑相似
  • 适合存放类级别的常量、工厂方法等
  • 避免在伴生对象中直接进行重型操作,建议用 by lazy

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/930746.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

libopenssl-1_0_0-devel-1.0.2p RPM 包安装教程(openSUSE/SLES x86_64)​

libopenssl-1_0_0-devel-1.0.2p RPM 包安装教程(openSUSE/SLES x86_64)​​一、这个包是干啥用的? 它是 ​OpenSSL 的开发文件包,不是 OpenSSL 本身运行时库。 libopenssl-1_0_0-devel-1.0.2p RPM安装包下载:http…

网站收录提交wordpress文章导入

从远端仓库克隆到本地 前提:本地要安装git,并且登录了账户 1.在要放这个远程仓库的路径下,打git 然后 git clone https://.. 如果要登录验证,那就验证下 克隆完后,cd 到克隆的路径, 可以用 git branch -a //查看分支名 git status //查看代码状态 删除…

云数据仓库十年架构演进与技术突破

本文深入解析某云数据仓库服务十年来的技术演进历程,涵盖架构设计、存储计算分离、自动化优化、多服务集成等核心技术突破,展示了从传统数据仓库到现代云原生架构的完整转型过程。云数据仓库的诞生与演进 近十年前,…

心理健康教育网站建设新十条优化措施

150. 逆波兰表达式求值 题目-中等难度示例1. 字典存储function2. if-else 题目-中等难度 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 ‘’、‘-’…

网站倒计时代码网页制作教程案例

一、总体概述 TypeScript 是 JavaScript 的超集&#xff0c;主要通过静态类型检查和丰富的类型系统来提高代码的健壮性和可维护性。它涵盖了从基础数据类型到高级类型、从函数与对象的类型定义到类、接口、泛型、模块化及装饰器等众多知识点。掌握这些内容有助于编写更清晰、结…

完整教程:SD卡通过读取bin文件替代读取图片格式文件来提高LCD显示速度

完整教程:SD卡通过读取bin文件替代读取图片格式文件来提高LCD显示速度2025-10-07 19:01 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: aut…

Claude 封杀中国后,我终于找到了平替!

就在这两天,AI 大模型界像约好了一样,扎堆发布新模型。9 月 29 日 DeepSeek-V3.2-Exp 发布,9 月 30 日 Claude 4.5 紧随其后发布……大家好,我是程序员鱼皮。国庆节本来想好好休息的,结果因为 AI 圈的疯狂内卷被迫…

20251007 模拟测 总结

\(\mathcal{Preface}\) 分数 \(100+100+100+25=325\)。 菜死了。 \(\mathcal{Problem \space{} A}\) Tag:循环,暴力枚举。 送分题,由于 \(1 \le l \le r \le 3000\) 且 \(1 \le nn \le 3000\),由此可知平方级别的时…

[退役感言]You are my only one.

感谢遇见 一生中最重要的人, 一生所挚爱的人, 最敬佩、最欣赏的人—— 你是我心目中 永远的队长,永远的战友; 顶天立地, 无可替代。 You are my only one.

深入解析:【后端架构师的发展路线】

深入解析:【后端架构师的发展路线】pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monac…

Mortal

Law 2 of thermodynamics states that \(dΩ_{isolated} \geq 0, dS_{\text{isolated}} \geq 0\)$ \(ΔS_isolated = ΔS_total = ΔS_sys + ΔS_env ≥ 0\) \(ΔS_{env} = -ΔH_{sys} / T\) constant pressure ΔS_to…

有学做美食的网站吗成都市住建局官网查询

在上一章中&#xff0c;我们已经了解了 C 中如何从函数返回数组&#xff0c;类似地&#xff0c;C 允许您从函数返回指针。为了做到这点&#xff0c;您必须声明一个返回指针的函数&#xff0c;如下所示&#xff1a; int * myFunction() { . . . } 另外&#xff0c;C 不支持在函数…

python,shell,linux,bash概念的不同和对比联系 - 指南

python,shell,linux,bash概念的不同和对比联系 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

怎么搭建一个网站物流软件app前十名

如今&#xff0c;我们似乎将整个生活都放在手机和移动设备上。他们用许多照片、备忘录、日历日期等记录了我们的生活&#xff0c;我们总是假设这些信息在我们需要时随时可以访问。但是&#xff0c;有许多情况会导致iPhone上的数据丢失&#xff0c;例如iPhone被盗&#xff0c;损…

API异常信息如何实时发送到钉钉 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

制作局域网连接打印机exe文件

核心是将bat脚本转换为exe文件。前提是局域网用户通过运行界面输入\\主机名,可连接到指定打印机。 编写打印机连接脚本 新建文本文档,在其中输入以下内容: @echo off rundll32 printui.dll PrintUIEntry /in /u /z …

深入解析:linux——账号和权限的管理

深入解析:linux——账号和权限的管理pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mona…

pandoc使用

pandoc安装 官网地址链接 如果在windows下安装,选择msi (Microsoft Installer),并根据引导完成安装工作。 安装完成后,需要打开新的terminal,并使用pandoc --version查看是否安装成功。 markdown转word 笔者在国内…

深入解析:(八)登录认证与学生写作画像

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …