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 的互操作性。
相关推荐
CANI_PLUS2 小时前
ESP32将DHT11温湿度传感器采集的数据上传到XAMPP的MySQL数据库
android·数据库·mysql
来来走走3 小时前
Flutter SharedPreferences存储数据基本使用
android·flutter
安卓开发者4 小时前
Android模块化架构深度解析:从设计到实践
android·架构
雨白4 小时前
HTTP协议详解(二):深入理解Header与Body
android·http
阿豪元代码5 小时前
深入理解 SurfaceFlinger —— 如何调试 SurfaceFlinger
android
阿豪元代码5 小时前
深入理解 SurfaceFlinger —— 概述
android
CV资深专家6 小时前
Launcher3启动
android
stevenzqzq7 小时前
glide缓存策略和缓存命中
android·缓存·glide
雅雅姐7 小时前
Android 16 的用户和用户组定义
android
没有了遇见7 小时前
Android ConstraintLayout 之ConstraintSet
android