Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • Kotlin 反射 API

Kotlin 反射 API

1. 反射的基本概念

反射(Reflection)是程序在运行时动态获取类信息、操作类属性或方法的能力。Kotlin 反射 API 基于 Java 反射,但提供了更简洁的语法和额外的功能。

1.1 反射的典型用途

  • 动态加载类
  • 运行时检查类结构(属性、方法等)
  • 动态调用方法或访问属性
  • 实现通用框架(如序列化、依赖注入)

2. Kotlin 反射 API 核心类

Kotlin 反射主要通过 kotlin-reflect 库实现,核心类位于 kotlin.reflect 包中:

类/接口说明
KClass表示类的引用,类似于 Java 的 Class
KProperty表示属性,包括扩展属性
KFunction表示函数,包括扩展函数
KType表示类型,包含泛型信息
KCallable可调用元素的超接口(函数和属性都继承此接口)

3. 基本反射操作

3.1 获取类的引用

// 1. 通过类名获取
val cls = MyClass::class

// 2. 通过对象实例获取
val obj = MyClass()
val cls2 = obj::class

// 3. 获取 Java Class 后转换
val javaClass = MyClass::class.java

3.2 获取类信息

data class Person(val name: String, val age: Int)

fun inspectClass(cls: KClass<*>) {
    println("类名: ${cls.simpleName}")
    println("属性:")
    cls.memberProperties.forEach { prop ->
        println("  ${prop.name}: ${prop.returnType}")
    }
    println("函数:")
    cls.memberFunctions.forEach { func ->
        println("  ${func.name}()")
    }
}

// 使用示例
inspectClass(Person::class)

3.3 动态创建实例

class User(val name: String)

fun createInstance(cls: KClass<*>, vararg args: Any?): Any? {
    val constructor = cls.constructors.firstOrNull()
    return constructor?.call(*args)
}

// 使用示例
val user = createInstance(User::class, "Alice") as User
println(user.name)  // 输出: Alice

3.4 动态访问属性和方法

class Calculator {
    val version = "1.0"
    
    fun add(a: Int, b: Int) = a + b
}

fun main() {
    val calc = Calculator()
    val kClass = calc::class
    
    // 访问属性
    val versionProp = kClass.memberProperties.find { it.name == "version" }
    println(versionProp?.get(calc))  // 输出: 1.0
    
    // 调用方法
    val addFunc = kClass.memberFunctions.find { it.name == "add" }
    val result = addFunc?.call(calc, 2, 3)
    println(result)  // 输出: 5
}

4. 高级反射特性

4.1 获取泛型类型信息

inline fun <reified T> getTypeInfo() {
    val type = typeOf<T>()
    println("Type: ${type.classifier}")
    println("Arguments: ${type.arguments.joinToString()}")
}

// 使用示例
getTypeInfo<List<String>>()
// 输出:
// Type: kotlin.collections.List
// Arguments: kotlin.String

4.2 可调用引用

Kotlin 支持将函数和属性转换为可调用引用:

fun square(x: Int) = x * x

fun main() {
    // 函数引用
    val squareRef = ::square
    println(squareRef(5))  // 输出: 25
    
    // 属性引用
    val str = "Hello"
    val lengthRef = String::length
    println(lengthRef(str))  // 输出: 5
}

4.3 反射与注解

结合反射可以检查和处理注解:

@Target(AnnotationTarget.CLASS)
annotation class Table(val name: String)

@Table(name = "users")
class User

fun main() {
    val tableAnnotation = User::class.annotations.find { it is Table } as? Table
    println(tableAnnotation?.name)  // 输出: users
}

5. 性能考虑与最佳实践

  1. 性能影响:反射操作比直接代码调用慢,应避免在性能关键路径使用
  2. 缓存反射结果:重复使用的反射对象应该缓存
  3. 使用 KCallable 接口:统一处理属性和方法
  4. 结合 reified 类型参数:在内联函数中获取类型信息
inline fun <reified T> createWithReflection(): T {
    return T::class.constructors.first().call()
}

6. 实际应用示例:简易 ORM 框架

// 定义实体注解
@Target(AnnotationTarget.CLASS)
annotation class Entity(val tableName: String)

@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)

// 实体类
@Entity(tableName = "users")
data class User(
    @Column(name = "user_id")
    val id: Int,
    
    @Column(name = "user_name")
    val name: String
)

// 反射工具类
object ORMUtils {
    fun <T : Any> createTable(entity: KClass<T>): String {
        val tableName = entity.annotations
            .filterIsInstance<Entity>()
            .firstOrNull()?.tableName ?: entity.simpleName?.lowercase() ?: "table"
        
        val columns = entity.memberProperties.map { prop ->
            val columnName = prop.annotations
                .filterIsInstance<Column>()
                .firstOrNull()?.name ?: prop.name
            "$columnName ${mapType(prop.returnType)}"
        }
        
        return "CREATE TABLE $tableName (${columns.joinToString()})"
    }
    
    private fun mapType(type: KType): String = when(type.classifier) {
        Int::class -> "INTEGER"
        String::class -> "TEXT"
        else -> "TEXT"
    }
}

// 使用示例
fun main() {
    val createSQL = ORMUtils.createTable(User::class)
    println(createSQL)
    // 输出: CREATE TABLE users (user_id INTEGER, user_name TEXT)
}

总结

Kotlin 反射 API 提供了强大的运行时自省能力,虽然性能开销较大,但在框架开发、动态功能实现等场景非常有用。合理使用反射可以极大增强程序的灵活性和扩展性。

注意:使用反射需要添加依赖:

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect:1.9.0")
}
Last Updated:: 5/21/25, 7:58 PM