Kotlin反射案例详解
一、反射基础与类引用
1.1 基本类引用操作
// 定义示例类
data class Person(
val name: String,
var age: Int,
private var salary: Double
) {
fun greet() = "Hello, I'm $name"
private fun secretMethod() = "Secret!"
companion object {
const val SPECIES = "Human"
fun createDefault() = Person("Unknown", 0, 0.0)
}
}
// 获取KClass引用
fun classReferences() {
// 获取KClass的多种方式
val personClass = Person::class
println("类名: ${personClass.simpleName}")
println("全限定名: ${personClass.qualifiedName}")
println("是否为数据类: ${personClass.isData}")
println("是否为密封类: ${personClass.isSealed}")
// 从实例获取KClass
val person = Person("Alice", 30, 50000.0)
val instanceClass = person::class
println("实例的类: ${instanceClass.simpleName}")
// 获取超类信息
println("超类: ${personClass.superclass}")
println("所有超类: ${personClass.allSuperclasses}")
}
1.2 构造器反射
fun constructorReflection() {
val personClass = Person::class
// 获取所有构造器
val constructors = personClass.constructors
println("构造器数量: ${constructors.size}")
// 获取主构造器
val primaryConstructor = personClass.primaryConstructor
primaryConstructor?.let { constructor ->
println("主构造器参数:")
constructor.parameters.forEach { param ->
println(" - ${param.name}: ${param.type}")
}
}
// 通过构造器创建实例
val constructor = personClass.primaryConstructor!!
val person = constructor.call("Bob", 25, 40000.0)
println("反射创建的对象: $person")
// 获取可空参数信息
val nullableConstructor = personClass.constructors.find {
it.parameters.size == 3 && it.parameters[0].type.isMarkedNullable
}
}
二、函数反射与调用
2.1 函数引用与反射调用
// 函数引用示例
fun functionReferences() {
// 方法引用
val greetFunc: KFunction<*> = Person::greet
println("函数名: ${greetFunc.name}")
println("返回类型: ${greetFunc.returnType}")
println("参数个数: ${greetFunc.parameters.size}")
// 调用函数
val person = Person("Charlie", 35, 60000.0)
val result = greetFunc.call(person)
println("调用结果: $result")
// 带参数的函数调用
val substringFunc = String::substring
val str = "Hello, World!"
val substring = substringFunc.call(str, 0, 5)
println("子字符串: $substring")
}
// 访问私有函数
fun accessPrivateFunctions() {
val personClass = Person::class
// 获取所有函数(包括私有)
val allFunctions = personClass.declaredFunctions
println("所有函数:")
allFunctions.forEach { function ->
println(" ${function.name} - 可见性: ${function.visibility}")
}
// 获取特定私有函数
val secretMethod = personClass.declaredFunctions
.find { it.name == "secretMethod" }
secretMethod?.let { method ->
// 设置可访问性
method.isAccessible = true
val person = Person("Dave", 40, 70000.0)
val result = method.call(person)
println("私有方法调用结果: $result")
// 恢复访问性
method.isAccessible = false
}
}
2.2 高阶函数反射
// 函数组合反射
fun functionCompositionReflection() {
// 定义函数类型
val double: (Int) -> Int = { it * 2 }
val square: (Int) -> Int = { it * it }
// 获取函数引用
val doubleRef = double::class
val squareRef = square::class
// 函数组合器
fun compose(f: (Int) -> Int, g: (Int) -> Int): (Int) -> Int = { x -> f(g(x)) }
// 反射分析函数组合
val composed = compose(double, square)
val composedRef = composed::class
println("组合函数类: ${composedRef.simpleName}")
// 使用反射调用
val result = composed.call(5)
println("组合函数结果: $result")
}
// Lambda表达式反射
fun lambdaReflection() {
val lambda: (String, Int) -> String = { str, times -> str.repeat(times) }
// Lambda的KFunction
val lambdaFunc = lambda as KFunction<*>
println("Lambda参数:")
lambdaFunc.parameters.forEachIndexed { index, param ->
println(" 参数$index: ${param.name ?: "未命名"} - ${param.type}")
}
// 获取Lambda的接收者(如果有)
val lambdaWithReceiver: String.(Int) -> String = { times -> this.repeat(times) }
val receiverFunc = lambdaWithReceiver as KFunction<*>
val receiverParam = receiverFunc.extensionReceiverParameter
println("Lambda接收者: ${receiverParam?.type}")
}
三、属性反射与操作
3.1 属性访问与修改
fun propertyReflection() {
val person = Person("Eve", 28, 45000.0)
val personClass = person::class
// 获取所有属性
val allProperties = personClass.declaredMemberProperties
println("所有属性:")
allProperties.forEach { prop ->
println(" ${prop.name}: ${prop.returnType} (只读: ${!prop is KMutableProperty<*>})")
}
// 访问属性值
val nameProp = personClass.declaredMemberProperties
.find { it.name == "name" } as KProperty1<Person, String>
val nameValue = nameProp.get(person)
println("Name属性值: $nameValue")
// 修改可变属性
val ageProp = personClass.declaredMemberProperties
.find { it.name == "age" } as KMutableProperty1<Person, Int>
ageProp.set(person, 29)
println("修改后的年龄: ${person.age}")
// 访问私有属性
val salaryProp = personClass.declaredMemberProperties
.find { it.name == "salary" } as KMutableProperty1<Person, Double>
salaryProp.isAccessible = true
val salaryValue = salaryProp.get(person)
println("私有属性salary: $salaryValue")
// 修改私有属性
salaryProp.set(person, 50000.0)
println("修改后的salary: ${salaryProp.get(person)}")
}
3.2 委托属性反射
// 自定义委托
class ObservableProperty<T>(
initialValue: T,
private val onChange: (T, T) -> Unit
) {
private var value: T = initialValue
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) {
val oldValue = value
value = newValue
onChange(oldValue, newValue)
}
}
class User {
var name: String by ObservableProperty("") { old, new ->
println("Name changed from $old to $new")
}
var age: Int by ObservableProperty(0) { old, new ->
println("Age changed from $old to $new")
}
}
// 委托属性反射
fun delegatedPropertyReflection() {
val user = User()
val userClass = user::class
// 获取委托属性
val properties = userClass.declaredMemberProperties
properties.forEach { property ->
println("属性: ${property.name}")
// 检查是否是委托属性
val javaField = userClass.java.getDeclaredField(property.name)
val isDelegated = javaField.isSynthetic
if (isDelegated) {
println(" 这是一个委托属性")
// 获取委托实例
val delegateField = userClass.java.getDeclaredField("\$\$delegated_properties")
delegateField.isAccessible = true
val delegates = delegateField.get(user) as? Array<*>
delegates?.forEach { delegate ->
println(" 委托: ${delegate?.javaClass?.simpleName}")
}
}
}
// 修改委托属性值
user.name = "Alice"
user.age = 30
}
四、注解处理与反射
4.1 自定义注解
// 定义注解
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class ApiEndpoint(val path: String, val method: String = "GET")
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Column(val name: String, val nullable: Boolean = false)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class DatabaseTable(val tableName: String)
// 使用注解的类
@DatabaseTable("users")
data class UserEntity(
@Column("user_id", nullable = false)
val id: Long,
@Column("user_name")
val name: String,
@Column("email", nullable = false)
val email: String,
@Column("created_at")
val createdAt: String = ""
)
// API控制器
class UserController {
@ApiEndpoint("/api/users", "GET")
fun getAllUsers(): List<UserEntity> {
return emptyList()
}
@ApiEndpoint("/api/users", "POST")
fun createUser(user: UserEntity): UserEntity {
return user
}
@ApiEndpoint("/api/users/{id}", "GET")
fun getUserById(id: Long): UserEntity? {
return null
}
}
4.2 注解反射处理
fun annotationProcessing() {
// 处理类注解
val userEntityClass = UserEntity::class
val tableAnnotation = userEntityClass.annotations
.find { it.annotationClass.simpleName == "DatabaseTable" }
(tableAnnotation as? DatabaseTable)?.let { annotation ->
println("表名: ${annotation.tableName}")
}
// 处理属性注解
userEntityClass.declaredMemberProperties.forEach { property ->
property.annotations.forEach { annotation ->
when (annotation) {
is Column -> {
println("属性 ${property.name} -> 列名: ${annotation.name}, 可空: ${annotation.nullable}")
}
}
}
}
// 处理方法注解
val controllerClass = UserController::class
val methods = controllerClass.declaredFunctions
println("API端点:")
methods.forEach { method ->
method.annotations.forEach { annotation ->
if (annotation is ApiEndpoint) {
println(" ${method.name}: ${annotation.method} ${annotation.path}")
}
}
}
}
// 注解处理器
class AnnotationProcessor {
fun generateSQL(entityClass: KClass<*>): String {
val tableAnnotation = entityClass.findAnnotation<DatabaseTable>()
?: throw IllegalArgumentException("类必须使用@DatabaseTable注解")
val columns = entityClass.declaredMemberProperties.mapNotNull { property ->
val columnAnnotation = property.findAnnotation<Column>()
columnAnnotation?.let { annotation ->
val columnName = annotation.name
val type = when (property.returnType.classifier) {
Long::class -> "BIGINT"
String::class -> "VARCHAR(255)"
else -> "TEXT"
}
val nullable = if (annotation.nullable) "" else "NOT NULL"
"$columnName $type $nullable"
}
}
return """
CREATE TABLE ${tableAnnotation.tableName} (
${columns.joinToString(",\n ")}
);
""".trimIndent()
}
fun scanApiEndpoints(controllerClass: KClass<*>): List<ApiEndpointInfo> {
return controllerClass.declaredFunctions.mapNotNull { function ->
function.findAnnotation<ApiEndpoint>()?.let { annotation ->
ApiEndpointInfo(
path = annotation.path,
method = annotation.method,
handler = function.name
)
}
}
}
data class ApiEndpointInfo(
val path: String,
val method: String,
val handler: String
)
}
五、动态代理与反射
5.1 动态代理实现
// 服务接口
interface UserService {
fun getUser(id: Long): UserEntity?
fun createUser(user: UserEntity): UserEntity
fun deleteUser(id: Long): Boolean
}
// 真实实现
class UserServiceImpl : UserService {
override fun getUser(id: Long): UserEntity? {
println("获取用户: $id")
return null
}
override fun createUser(user: UserEntity): UserEntity {
println("创建用户: ${user.name}")
return user
}
override fun deleteUser(id: Long): Boolean {
println("删除用户: $id")
return true
}
}
// 动态代理处理器
class LoggingInvocationHandler(
private val target: Any
) : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any? {
println("方法调用前: ${method.name}")
val startTime = System.currentTimeMillis()
val result = try {
method.invoke(target, *(args ?: emptyArray()))
} catch (e: Exception) {
println("方法调用异常: ${e.message}")
throw e
}
val duration = System.currentTimeMillis() - startTime
println("方法调用后: ${method.name}, 耗时: ${duration}ms")
return result
}
}
// 缓存代理
class CachingInvocationHandler(
private val target: Any
) : InvocationHandler {
private val cache = mutableMapOf<String, Any?>()
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any? {
// 只缓存get方法
if (!method.name.startsWith("get")) {
return method.invoke(target, *(args ?: emptyArray()))
}
val cacheKey = "${method.name}:${args?.contentToString() ?: ""}"
return if (cache.containsKey(cacheKey)) {
println("缓存命中: $cacheKey")
cache[cacheKey]
} else {
val result = method.invoke(target, *(args ?: emptyArray()))
cache[cacheKey] = result
println("缓存存储: $cacheKey")
result
}
}
}
// 创建动态代理
fun createDynamicProxy() {
val realService = UserServiceImpl()
// 创建日志代理
val loggingProxy = Proxy.newProxyInstance(
UserService::class.java.classLoader,
arrayOf(UserService::class.java),
LoggingInvocationHandler(realService)
) as UserService
// 创建缓存代理
val cachingProxy = Proxy.newProxyInstance(
UserService::class.java.classLoader,
arrayOf(UserService::class.java),
CachingInvocationHandler(realService)
) as UserService
// 使用代理
loggingProxy.getUser(1L)
cachingProxy.getUser(1L)
cachingProxy.getUser(1L) // 第二次调用应该命中缓存
}
5.2 Kotlin动态代理扩展
// Kotlin风格的动态代理
inline fun <reified T : Any> createProxy(
crossinline handler: (method: Method, args: Array<out Any>?) -> Any?
): T {
return Proxy.newProxyInstance(
T::class.java.classLoader,
arrayOf(T::class.java)
) { _, method, args ->
handler(method, args)
} as T
}
// 验证代理
fun validationProxy() {
interface ValidatedService {
@RequiresPermission("read")
fun readData(): String
@RequiresPermission("write")
fun writeData(data: String)
}
val currentPermissions = setOf("read")
val service = createProxy<ValidatedService> { method, args ->
// 检查方法注解
val permissionAnnotation = method.getAnnotation(RequiresPermission::class.java)
if (permissionAnnotation != null &&
!currentPermissions.contains(permissionAnnotation.value)) {
throw SecurityException("缺少权限: ${permissionAnnotation.value}")
}
// 模拟真实调用
when (method.name) {
"readData" -> "Data from server"
"writeData" -> println("Writing: ${args?.firstOrNull()}")
else -> null
}
}
try {
service.readData() // 应该成功
service.writeData("test") // 应该失败
} catch (e: SecurityException) {
println("权限错误: ${e.message}")
}
}
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class RequiresPermission(val value: String)
六、序列化与反射
6.1 反射序列化器
class ReflectionSerializer {
fun <T : Any> serialize(obj: T): String {
val clazz = obj::class
val properties = clazz.declaredMemberProperties
val jsonProperties = properties.mapNotNull { property ->
property.isAccessible = true
val value = property.get(obj)
value?.let {
""""${property.name}": ${serializeValue(it)}"""
}
}
return "{${jsonProperties.joinToString(", ")}}"
}
private fun serializeValue(value: Any): String {
return when (value) {
is String -> """"$value""""
is Number, is Boolean -> value.toString()
else -> """"${value.toString()}""""
}
}
inline fun <reified T : Any> deserialize(json: String): T {
// 简化版JSON解析
val properties = json.trim('{', '}')
.split(",")
.associate {
val parts = it.split(":")
parts[0].trim(' ', '"') to parts[1].trim()
}
val constructor = T::class.primaryConstructor!!
val args = mutableMapOf<KParameter, Any?>()
constructor.parameters.forEach { param ->
val value = properties[param.name]
args[param] = when (param.type.classifier) {
String::class -> value?.trim('"')
Int::class -> value?.toInt()
Long::class -> value?.toLong()
Boolean::class -> value?.toBoolean()
else -> value
}
}
return constructor.callBy(args)
}
}
// 使用示例
fun serializationDemo() {
data class Product(
val id: Long,
val name: String,
val price: Double,
val inStock: Boolean
)
val product = Product(1, "Laptop", 999.99, true)
val serializer = ReflectionSerializer()
val json = serializer.serialize(product)
println("序列化: $json")
val deserialized = serializer.deserialize<Product>(json)
println("反序列化: $deserialized")
}
6.2 反射深拷贝
class ReflectionCloner {
fun <T : Any> deepCopy(obj: T): T {
val clazz = obj::class
if (clazz.isData) {
return cloneDataClass(obj, clazz)
}
return cloneRegularClass(obj, clazz)
}
private fun <T : Any> cloneDataClass(obj: T, clazz: KClass<T>): T {
val constructor = clazz.primaryConstructor!!
val args = mutableMapOf<KParameter, Any?>()
constructor.parameters.forEach { param ->
val property = clazz.declaredMemberProperties
.find { it.name == param.name }
property?.let {
it.isAccessible = true
val value = it.get(obj)
args[param] = deepCopyValue(value)
}
}
return constructor.callBy(args)
}
private fun <T : Any> cloneRegularClass(obj: T, clazz: KClass<T>): T {
// 通过复制构造函数或工厂方法
val copyConstructor = clazz.constructors.find { it.parameters.size == 1 }
return if (copyConstructor != null) {
copyConstructor.call(obj)
} else {
// 使用序列化/反序列化
val serializer = ReflectionSerializer()
val json = serializer.serialize(obj)
serializer.deserialize(json)
}
}
private fun deepCopyValue(value: Any?): Any? {
return when (value) {
null -> null
is String, is Number, is Boolean -> value
is Collection<*> -> value.map { deepCopyValue(it) }
is Map<*, *> -> value.mapValues { deepCopyValue(it.value) }
else -> deepCopy(value)
}
}
}
七、性能优化与缓存
7.1 反射缓存策略
class CachedReflectionAccessor<T : Any>(private val clazz: KClass<T>) {
// 缓存构造器
private val constructorCache = lazy {
clazz.primaryConstructor ?: throw IllegalArgumentException("没有主构造器")
}
// 缓存属性
private val propertyCache = lazy {
clazz.declaredMemberProperties.associateBy { it.name }
}
// 缓存方法
private val methodCache = lazy {
clazz.declaredFunctions.associateBy { it.name }
}
// 带缓存的实例化
fun newInstance(vararg args: Any?): T {
return constructorCache.value.call(*args)
}
// 带缓存的属性访问
fun getProperty(instance: T, propertyName: String): Any? {
val property = propertyCache.value[propertyName]
?: throw NoSuchFieldError("属性不存在: $propertyName")
property.isAccessible = true
return property.get(instance)
}
// 带缓存的方法调用
fun callMethod(instance: T, methodName: String, vararg args: Any?): Any? {
val method = methodCache.value[methodName]
?: throw NoSuchMethodError("方法不存在: $methodName")
method.isAccessible = true
return method.call(instance, *args)
}
}
// 使用示例
fun cachedReflectionDemo() {
data class Order(
val id: Long,
val items: List<String>,
var status: String = "PENDING"
) {
fun calculateTotal(): Double {
return items.size * 10.0
}
}
val accessor = CachedReflectionAccessor(Order::class)
// 创建实例
val order = accessor.newInstance(1L, listOf("Item1", "Item2"), "PROCESSING")
// 访问属性
val status = accessor.getProperty(order, "status")
println("状态: $status")
// 调用方法
val total = accessor.callMethod(order, "calculateTotal")
println("总计: $total")
// 性能对比
val iterations = 10000
// 无缓存反射
var start = System.currentTimeMillis()
repeat(iterations) {
Order::class.declaredMemberProperties.find { it.name == "status" }?.get(order)
}
println("无缓存耗时: ${System.currentTimeMillis() - start}ms")
// 有缓存反射
start = System.currentTimeMillis()
repeat(iterations) {
accessor.getProperty(order, "status")
}
println("有缓存耗时: ${System.currentTimeMillis() - start}ms")
}
八、实战案例:ORM框架
8.1 简单ORM实现
// 实体注解
@Target(AnnotationTarget.CLASS)
annotation class Entity(val tableName: String)
@Target(AnnotationTarget.PROPERTY)
annotation class Id
@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)
// 实体类
@Entity("users")
data class User(
@Id
val id: Long,
@Column("username")
val name: String,
@Column("email")
val email: String,
@Column("age")
val age: Int
)
// ORM映射器
class OrmMapper {
private val entityCache = mutableMapOf<KClass<*>, EntityInfo>()
data class EntityInfo(
val tableName: String,
val idColumn: PropertyInfo,
val columns: List<PropertyInfo>
)
data class PropertyInfo(
val property: KProperty<*>,
val columnName: String,
val isId: Boolean = false
)
inline fun <reified T : Any> getEntityInfo(): EntityInfo {
return getEntityInfo(T::class)
}
fun <T : Any> getEntityInfo(clazz: KClass<T>): EntityInfo {
return entityCache.getOrPut(clazz) {
val entityAnnotation = clazz.findAnnotation<Entity>()
?: throw IllegalArgumentException("类必须使用@Entity注解")
val properties = clazz.declaredMemberProperties.mapNotNull { property ->
val columnAnnotation = property.findAnnotation<Column>()
val isId = property.findAnnotation<Id>() != null
when {
isId -> PropertyInfo(property, "id", true)
columnAnnotation != null -> PropertyInfo(property, columnAnnotation.name)
else -> null
}
}
val idColumn = properties.find { it.isId }
?: throw IllegalArgumentException("实体必须有一个@Id字段")
EntityInfo(entityAnnotation.tableName, idColumn, properties)
}
}
fun <T : Any> toInsertSQL(entity: T): Pair<String, List<Any?>> {
val info = getEntityInfo(entity::class)
val columnNames = info.columns.filterNot { it.isId }
.map { it.columnName }
val placeholders = columnNames.map { "?" }
val values = columnNames.map { columnName ->
val property = info.columns.find { it.columnName == columnName }?.property
property?.isAccessible = true
property?.get(entity)
}
val sql = """
INSERT INTO ${info.tableName}
(${columnNames.joinToString(", ")})
VALUES (${placeholders.joinToString(", ")})
""".trimIndent()
return sql to values
}
fun <T : Any> toSelectSQL(clazz: KClass<T>, id: Any): Pair<String, List<Any?>> {
val info = getEntityInfo(clazz)
val sql = """
SELECT * FROM ${info.tableName}
WHERE ${info.idColumn.columnName} = ?
""".trimIndent()
return sql to listOf(id)
}
fun <T : Any> fromResultSet(resultSet: Map<String, Any?>, clazz: KClass<T>): T {
val info = getEntityInfo(clazz)
val constructor = clazz.primaryConstructor!!
val args = mutableMapOf<KParameter, Any?>()
constructor.parameters.forEach { param ->
val propertyInfo = info.columns.find {
it.property.name == param.name
}
val value = if (propertyInfo != null) {
resultSet[propertyInfo.columnName]
} else {
null
}
args[param] = value
}
return constructor.callBy(args)
}
}
// 使用示例
fun ormDemo() {
val mapper = OrmMapper()
val user = User(1, "john_doe", "john@example.com", 30)
// 生成插入SQL
val (insertSQL, insertValues) = mapper.toInsertSQL(user)
println("插入SQL: $insertSQL")
println("参数: $insertValues")
// 生成查询SQL
val (selectSQL, selectValues) = mapper.toSelectSQL(User::class, 1L)
println("查询SQL: $selectSQL")
println("参数: $selectValues")
// 模拟从数据库读取数据
val resultSet = mapOf(
"id" to 1L,
"username" to "john_doe",
"email" to "john@example.com",
"age" to 30
)
val reconstructedUser = mapper.fromResultSet(resultSet, User::class)
println("重建的用户: $reconstructedUser")
}
九、安全注意事项
9.1 反射安全实践
class SecureReflectionHandler {
// 白名单控制的反射访问
private val allowedClasses = setOf(
"com.example.models.User",
"com.example.models.Product"
)
private val allowedMethods = setOf(
"toString",
"equals",
"hashCode"
)
fun safeReflectionCall(className: String, methodName: String): Any? {
// 检查类是否在白名单中
if (!allowedClasses.contains(className)) {
throw SecurityException("不允许访问类: $className")
}
// 检查方法是否在白名单中
if (!allowedMethods.contains(methodName)) {
throw SecurityException("不允许调用方法: $methodName")
}
// 安全地加载类
val clazz = Class.forName(className)
// 只允许访问public方法
val method = clazz.getMethod(methodName)
method.isAccessible = false // 确保不使用setAccessible
// 创建实例并调用方法
val instance = clazz.getDeclaredConstructor().newInstance()
return method.invoke(instance)
}
// 防止反射修改final字段
fun protectFinalFields() {
val clazz = String::class.java
val valueField = clazz.getDeclaredField("value")
// 尝试修改final字段(应该失败)
try {
valueField.isAccessible = true
valueField.set("immutable", "modified".toCharArray())
} catch (e: IllegalAccessException) {
println("安全保护生效: 无法修改final字段")
}
}
}
// 使用SecurityManager
fun withSecurityManager() {
val securityManager = object : SecurityManager() {
override fun checkMemberAccess(clazz: Class<*>, which: Int) {
if (which == Member.PUBLIC) {
return
}
// 禁止访问非public成员
val stack = classContext
if (stack.any { it.name.contains("Reflection")) {
throw SecurityException("禁止使用反射访问非public成员")
}
}
override fun checkPackageAccess(pkg: String) {
if (pkg.startsWith("java.lang.reflect")) {
throw SecurityException("禁止使用反射包")
}
}
}
// 安装SecurityManager
System.setSecurityManager(securityManager)
try {
// 尝试反射访问
val clazz = String::class.java
val field = clazz.getDeclaredField("value")
field.isAccessible = true
println("反射访问成功")
} catch (e: SecurityException) {
println("SecurityManager阻止了反射访问: ${e.message}")
}
}
十、性能最佳实践
10.1 反射性能优化
class OptimizedReflection {
// 1. 缓存Method/Field对象
private val methodCache = ConcurrentHashMap<String, Method>()
private val fieldCache = ConcurrentHashMap<String, Field>()
fun cachedMethodCall(obj: Any, methodName: String): Any? {
val cacheKey = "${obj.javaClass.name}.$methodName"
val method = methodCache.getOrPut(cacheKey) {
obj.javaClass.getDeclaredMethod(methodName).apply {
isAccessible = true
}
}
return method.invoke(obj)
}
// 2. 使用MethodHandle(性能更好)
private val methodHandles = ConcurrentHashMap<String, MethodHandle>()
fun methodHandleCall(obj: Any, methodName: String): Any? {
val cacheKey = "${obj.javaClass.name}.$methodName"
val methodHandle = methodHandles.getOrPut(cacheKey) {
val lookup = MethodHandles.lookup()
val method = obj.javaClass.getDeclaredMethod(methodName)
lookup.unreflect(method)
}
return methodHandle.invoke(obj)
}
// 3. 使用invokedynamic(高级优化)
// 注意:这需要Java 7+和字节码操作
// 4. 避免频繁的isAccessible调用
fun efficientPropertyAccess() {
data class Data(val value: String)
val data = Data("test")
val field = Data::class.java.getDeclaredField("value")
// 不好的做法:每次调用都设置accessible
repeat(1000) {
field.isAccessible = true
val value = field.get(data)
field.isAccessible = false
}
// 好的做法:只设置一次
field.isAccessible = true
repeat(1000) {
val value = field.get(data)
}
field.isAccessible = false
}
// 5. 使用原生反射替代Kotlin反射(某些场景)
fun comparePerformance() {
class Sample {
private val data = "Hello"
fun getData() = data
}
val sample = Sample()
val iterations = 100000
// Kotlin反射
var start = System.currentTimeMillis()
repeat(iterations) {
val property = Sample::class.declaredMemberProperties.find { it.name == "data" }
property?.isAccessible = true
property?.get(sample)
}
println("Kotlin反射耗时: ${System.currentTimeMillis() - start}ms")
// Java反射
start = System.currentTimeMillis()
repeat(iterations) {
val field = Sample::class.java.getDeclaredField("data")
field.isAccessible = true
field.get(sample)
}
println("Java反射耗时: ${System.currentTimeMillis() - start}ms")
// 直接访问
start = System.currentTimeMillis()
repeat(iterations) {
sample.getData()
}
println("直接访问耗时: ${System.currentTimeMillis() - start}ms")
}
}
总结
反射是强大的工具,但需要谨慎使用:
- 性能:反射比直接调用慢10-100倍,需要缓存反射对象
- 安全:反射可以绕过访问控制,需要适当的安全措施
- 维护性:反射代码更难理解和调试
- 类型安全:反射绕过了编译时类型检查
最佳实践建议:
- 只在必要时使用反射(框架、库、序列化等)
- 缓存反射对象(Method、Field、Constructor)
- 优先使用Kotlin反射API,但在性能关键处考虑Java反射
- 实施适当的安全检查
- 编写全面的单元测试
- 考虑使用代码生成作为反射的替代方案