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

Kotlin中声明常量的最优方式:伴生对象还是类成员?

Kotlin两种常量声明方式的优劣分析

两种写法的本质区别

  • 伴生对象中的const val:对应Java的静态常量,属于类本身,全局仅存在一份实例,类加载时初始化,直到类被卸载才会释放(类卸载条件苛刻,通常程序运行期间会一直存在)。
  • 类成员的private val:属于类的每个实例,每个对象都会持有一个对常量的引用,实例被GC回收时,这个引用会被释放。

纠正内存认知误区

你提到的“非静态常量会在每个对象中分配内存”需要补充:对于字符串字面量(比如例子中的"A"),它本身会被存入字符串常量池,所有引用它的对象都是指向常量池中的同一个实例。也就是说,实例成员的val a = "A"并不会为字符串本身分配新内存,只是每个实例多了一个8字节左右的引用(64位系统),字符串本体的内存占用是共享的。

而伴生对象的静态常量,同样是引用常量池中的字符串,只是这个引用属于类,全局唯一。

选择建议

  1. 语义优先:如果常量是类级别的通用配置、固定参数,和实例无关,优先用伴生对象的const val——这能明确表达“这是属于整个类的常量”的语义,即使是private修饰,代码可读性也更强。
  2. 实例关联场景:如果常量的值和实例强绑定(比如每个实例的常量值由构造参数决定),那必须用类成员的val。
  3. 内存考量:
    • 如果你的类会被创建大量实例(比如十万级以上),实例成员的引用总内存可能需要考虑,这时用静态常量更节省内存。
    • 如果只是普通场景,少量实例,两种方式的内存差异可以忽略,没必要为了这点差异牺牲语义清晰度。

关于静态常量的内存驻留

你担心“100个以上静态常量会一直驻留内存”——实际上,字符串常量本身在常量池里是复用的,即使有100个不同的字符串,它们的总内存也只是这些字符串的字节数之和,而静态引用的内存开销微乎其微。只有当常量是大型对象(比如大数组、复杂对象)时,才需要考虑驻留内存的问题,普通字符串常量完全不用过度担心。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 00:01:09