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 的互操作性。
相关推荐
2501_915909061 小时前
iOS应用性能优化:十大策略提升用户体验与开发效率
android·ios·小程序·https·uni-app·iphone·webview
sun0077001 小时前
打通android全链路,网卡驱动, 内核 , 到上层hal, framework
android
awu的Android笔记2 小时前
Android VpnService:如何把所有流量导入用户态
android
plainGeekDev2 小时前
AlertDialog → DialogFragment
android·java·kotlin
流星白龙2 小时前
【MySQL高阶】13.其他存储引擎
android·数据库·mysql
Lyyaoo.2 小时前
【MySQL】SQL优化
android·sql·mysql
ImTryCatchException2 小时前
Android 性能优化实战手册:从理论到落地的完整方法论
android·性能优化
sun0077003 小时前
qnx网络相关模块,全链路,硬件网卡 → 用户态驱动 (.so) → io‑pkt/io‑sock(用户态 TCP/IP + 转发 + 控制)
android
赏金术士3 小时前
Android app 项目:模块打包 AAR 教程
android·热修复·tinker·aar打包
ImTryCatchException3 小时前
React Native 嵌入现有 Android 项目:踩坑记录与解决方案
android·react native·react.js