Kotlin伴生类

在 Kotlin 中,‌伴生对象(Companion Object) ‌ 是用于替代 Java 中 static 成员的关键机制,但功能更强大且灵活。以下是其核心特性和用法:


一、核心概念

  1. 替代静态成员
    Kotlin 没有 static 关键字,伴生对象用于定义类的"静态"属性和方法。
  2. 单例性
    每个类的伴生对象是唯一的单例实例,在类加载时初始化。
  3. 可命名性
    伴生对象可以命名(默认名称为 Companion),提高可读性。

二、基本语法

1. 定义伴生对象

kotlin 复制代码
class MyClass {
    companion object {
        const val TAG = "MyClass" // 常量
        fun create(): MyClass = MyClass() // 工厂方法
    }
}

2. 访问伴生对象成员

scss 复制代码
// 通过类名直接访问(类似静态调用)
val instance = MyClass.create() 
println(MyClass.TAG) // 输出: MyClass

3. 命名伴生对象

kotlin 复制代码
class User {
    companion object Factory { // 命名为 Factory
        fun create(name: String): User = User(name)
    }
}

// 调用方式
val user = User.Factory.create("Alice")

三、使用场景

1. 工厂模式

通过伴生对象隐藏构造函数细节:

kotlin 复制代码
class Connection private constructor() {
    companion object {
        fun create(): Connection {
            // 初始化逻辑
            return Connection()
        }
    }
}

// 使用
val conn = Connection.create()

2. 常量定义

替代 Java 的静态常量:

kotlin 复制代码
class Constants {
    companion object {
        const val MAX_SIZE = 1024
        const val API_URL = "https://api.example.com"
    }
}

// 调用
println(Constants.MAX_SIZE)

3. 实现接口

伴生对象可以实现接口,增强扩展性:

kotlin 复制代码
interface JsonFactory<T> {
    fun fromJson(json: String): T
}

class Data {
    companion object : JsonFactory<Data> {
        override fun fromJson(json: String): Data {
            // 解析逻辑
            return Data()
        }
    }
}

// 通过接口调用
val data = Data.fromJson("{...}")

四、高级特性

1. 初始化逻辑

伴生对象支持 init 代码块:

kotlin 复制代码
class Logger {
    companion object {
        init {
            // 初始化日志配置(首次访问时执行)
            println("Logger initialized")
        }
    }
}

2. 扩展函数

可为伴生对象定义扩展函数:

kotlin 复制代码
class MyClass {
    companion object 
}

// 扩展函数
fun MyClass.Companion.printInfo() {
    println("This is MyClass")
}

// 调用
MyClass.printInfo()

五、与 Java 互操作

1. 暴露为静态成员

使用 @JvmStatic@JvmField 让伴生对象成员在 Java 中像静态成员一样调用:

less 复制代码
class KotlinClass {
    companion object {
        @JvmStatic
        fun staticMethod() {} 

        @JvmField
        val MAX = 100
    }
}

// Java 调用
KotlinClass.staticMethod(); 
int max = KotlinClass.MAX;

2. 访问伴生对象实例

在 Java 中可以通过 Companion 访问伴生对象:

scss 复制代码
// Java 代码
KotlinClass.Companion.getMAX(); // 无 @JvmField 时

六、注意事项

  1. 懒加载
    伴生对象在类首次被访问时初始化(线程安全)。
  2. 不可访问实例成员
    伴生对象无法直接访问外部类的实例成员(因为它是静态作用域)。
  3. 命名伴生对象的意义
    命名可提高代码可读性,尤其是在需要明确职责时(如 FactorySerializer)。

七、与对象表达式对比

特性 伴生对象 普通对象表达式
生命周期 与类绑定(单例) 临时对象(随作用域结束销毁)
访问方式 通过类名直接访问 需赋值给变量或直接使用
用途 替代静态成员、工厂模式等 临时实现接口或匿名类

总结

  • 伴生对象是 Kotlin 实现静态行为的推荐方式‌,兼具单例性和灵活性。
  • 通过 companion object 定义常量、工厂方法或实现接口。
  • 使用 @JvmStatic@JvmField 优化与 Java 的互操作性。
相关推荐
Kapaseker4 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴4 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭14 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab15 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
BoomHe20 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农1 天前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少1 天前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker1 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋1 天前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我2 天前
让我们实现一个更好看的内部阴影按钮
android·flutter