反射是一种机制,它允许我们在运行时检查、修改和操作类或对象的内部结构。反射开启了动态编程的可能性,在开发库、框架或工具等场景中非常有用。


Java 中的反射

在 Java 中,反射一直是实现动态编程的重要基石。它允许开发者在不提前知道类名的情况下,于运行时检查类、接口、字段和方法。

Class stringClass = String.class;
Method[] methods = stringClass.getMethods();

代码解释

  • String.class 获取 String 类对应的 Class 对象。

  • getMethods() 返回该类(以及其父类)的所有 公共方法 数组。


Kotlin 对反射的需求

虽然 Java 的反射功能很强大,但 Kotlin 引入了许多额外的语言特性,例如 数据类扩展函数可空类型 等,这些特性需要额外的反射能力。
Kotlin 提供了 kotlin.reflect 包来支持这些 Kotlin 特有的功能,允许对函数、属性和类等语言元素进行检查和操作。


Kotlin 反射依赖添加

Gradle (Kotlin DSL)

dependencies {implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.22")
}

解释:为项目引入 kotlin-reflect 库,以支持 Kotlin 反射功能。

Gradle (Groovy DSL)

dependencies {implementation "org.jetbrains.kotlin:kotlin-reflect:1.8.22"
}

解释:与 Kotlin DSL 相同,只是写法不同。

Maven

<dependencies><dependency><groupId>org.jetbrains.kotlin</groupId><artifactId>kotlin-reflect</artifactId></dependency>
</dependencies>

解释:在 Maven 项目中引入 Kotlin 反射库。


数据类示例(无反射)

data class Source(val name: String, val age: Int)
data class Target(var name: String? = null, var age: Int = 0)val source = Source("John", 20)val target = Target().apply {name = source.nameage = source.age
}

解释
手动将 Source 的属性赋值给 Target。当属性较多或运行时无法确定属性名时,这种方法会变得繁琐。


使用反射实现通用属性映射

fun <S : Any, T : Any> map(source: S, target: T) {val sourceProperties = source::class.memberPropertiesval targetProperties = target::class.memberPropertiessourceProperties.forEach { sourceProperty ->targetProperties.find { it.name == sourceProperty.name }?.let { targetProperty ->if (targetProperty is KMutableProperty<*>) {targetProperty.setter.call(target, sourceProperty.getter.call(source))}}}
}val target = Target()
map(source, target)

解释

  • source::class.memberProperties 获取源对象的所有属性。

  • 找到与源属性同名的目标属性,并调用 setter 方法赋值。

  • 泛型 <S, T> 使得该方法适用于任意两个类(只要属性名匹配)。


Kotlin 反射核心类

val stringClass = String::class
val stringType = stringClass.starProjectedType

解释

  • KClass:Kotlin 类的反射对象。

  • KCallable:函数与属性的通用接口。

  • KFunction:函数的反射对象。

  • KProperty:属性的反射对象。


基本操作示例

  1. 实例化类
val stringClass = String::class
val instance = stringClass.createInstance()

代码解释

  • String::class获取 Kotlin 的 KClass 对象(表示 String 类的元信息)
  • stringClass.createInstance()调用该类的 无参构造函数(primary constructor)来创建一个新的(String)实例。
  1. 调用方法
val function = String::toLowerCase
val result = function.call("HELLO")  // "hello"

代码解释

  • 通过 Kotlin 反射 获取类的属性引用 (:😃。
  • 动态调用 toLowerCase 方法,并传入"HELLO" 作为 调用者(也就是接收者对象)。。
  1. 访问与修改属性
data class Person(val name: String, var age: Int)val person = Person("John", 20)
val ageProperty = Person::age
println(ageProperty.get(person))  // 20
ageProperty.set(person, 21)
println(person.age)  // 21

代码解释

  • 通过 Kotlin 反射 获取类的属性引用 (:😃。
  • 用 get() 和 set() 在运行时(传入接收者对象)读取与修改属性值。

高级操作

  1. 泛型类型信息.
val list = listOf(1, 2, 3)
val type = list::class.typeParameters
println(type)  // [E]

代码解释

  • 返回该类在定义时的泛型形参列表
  1. 高阶函数参数类型
fun foo(block: () -> Unit) { block() }val function = ::foo
val parameter = function.parameters.first()
println(parameter.type)  // Function0<kotlin.Unit>

代码解释

  • 获取函数 foo 的引用,赋给 function 变量。(function的类型是KFunction)
  • 返回一个包含该函数所有参数的列表(类型为 KParameter)
  • 取第一个参数,也就是这里的 block
  • 打印该参数的 Kotlin 类型

反射的优势与限制
优势

  • 实现动态功能(如通用对象映射、设计模式等)
  • 框架与库开发中不可或缺

限制

  • 性能开销大(运行时计算多)
  • 可能引发安全问题(访问私有成员)
  • 并非所有类都能通过反射实例化(如匿名类、内部类)

总结

在 Kotlin 中,反射是一个功能强大的运行时检查与操作工具,可用于:

  • 自动对象映射
  • 实现设计模式
  • 框架与库开发

但需要谨慎使用,避免在性能敏感或安全性要求高的场景中滥用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/918399.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918399.shtml
英文地址,请注明出处:http://en.pswp.cn/news/918399.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习嵌入式-IMX6ULL学习——中断

volatile&#xff1a;易变的&#xff0c;防止系统优化对寄存器做处理的时候使用&#xff0c;在进行写1清零操作时&#xff0c;防止该操作被系统优化&#xff1b;一、GIC通用中断控制器1.GIC通用中断控制器GIC接收众多外部中断&#xff0c;然后对其进行处理&#xff0c;最终通过…

HENGSHI SENSE 6.0 功能-AI 查数助手

面向所有AI Agent开放BI和数据分析能力 AI 查数助手 6.0版本中&#xff0c;我们AI助手的优化是比较深入且全面的。从问答效率到集成能力&#xff0c;都得到了大的跃升&#xff0c;是智能问数应用场景的重大升级以及体验的全方位优化。我们优化了 AI 助手执行流程&#xff0c;…

降压型DCDC电源芯片推荐-芯伯乐XBL4001 40V/5A

在电子设备不断追求高性能与低功耗的今天&#xff0c;电源管理芯片的重要性不言而喻。芯伯乐主推的XBLW-XBL4001芯片&#xff0c;凭借其出色的设计与稳定的性能&#xff0c;为电源管理领域带来了一款实用的新选择。一、芯片概述XBLW-XBL4001是一款降压型&#xff08;Buck&#…

uni-app app端安卓和ios如何申请麦克风权限,唤起提醒弹框

代码包含功能如下&#xff1a; 1、判断推送权限是否开启 2、判断定位权限是否开启 3、判断麦克风权限是否开启 4、判断相机权限是否开启 5、判断相册权限是否开启 6、判断通讯录权限是否开启 7、判断日历权限是否开启 8、判断备忘录权限是否开启 9、Android权限查询 10、检查系…

关于 Rust 异步(无栈协程)的相关疑问

这是一个记录问题求助的文章。关于 waker 与运行时的合作方式我肤浅地学习了 Rust 异步底层实现原理&#xff0c;关于 Future、waker 和运行时等。关于 waker 我有三点猜测&#xff1a;waker 是由实现执行器的人提供的在执行器中会调用 epoll_wait&#xff0c;epoll 返回 fd&am…

stm32项目(25)——基于stm32的植物生长箱环境监测系统

1.实现功能 测 环境温湿度、光照强度、土壤湿度、水箱水位 手机APP显示 温度过低-->打开加热板 湿度过低-->打开水泵 土壤湿度低-->开水泵 --->只要有指标低于阈值时 就蜂鸣器报警 光强弱-->补光 水位低-->抽水 OLED屏幕实时显示各种信息 分…

golang 基础案例_02

1.锁有时候我们的代码中可能会存在多个 goroutine 同时操作一个资源&#xff08;临界区&#xff09;的情况&#xff0c;这种情况下就会发生竞态问题&#xff08;数据竞态&#xff09;。(1)、互斥锁&#xff1b;(2)、读写互斥锁&#xff1b;(3)、sync.WaitGroup&#xff1b;(4)、…

C++算法·前缀和

前缀和(Prefix(Prefix(Prefix Sum)Sum)Sum)的定义 前缀和是一种高效处理区间求和问题的算法技巧 其核心思想是通过预处理构建一个前缀和数组 使得后续的区间和查询可以在常数时间O(1)O(1)O(1)内完成 核心概念 定义 给定一个数组a[1...n]a[1...n]a[1...n],其前缀和数组s[1...…

JavaEE 初阶第十七期:文件 IO 的 “管道艺术”(下)

专栏&#xff1a;JavaEE初阶起飞计划 个人主页&#xff1a;手握风云 目录 一、Java文件内容写入 1.1. OutputStream 二、字符流读取和写入 2.1. Reader 2.2. Writer 三、示例练习 3.1. 查找文件功能 一、Java文件内容写入 1.1. OutputStream OutputStream同样只是⼀个抽…

【liunx】web高可用---nginx

NGINX简介Nginx&#xff08;发音为 “engine x”&#xff09;是一款由俄罗斯程序员 Igor Sysoev 开发的 轻量级、高性能的 HTTP 和反向代理服务器&#xff0c;同时也是一个 IMAP/POP3/SMTP 代理服务器。自 2004 年首次发布以来&#xff0c;Nginx 凭借其 高并发处理能力、低内存…

FPGA+护理:跨学科发展的探索(二)

FPGA护理&#xff1a;跨学科发展的探索&#xff08;二&#xff09; 系列文章目录 FPGA护理&#xff1a;跨学科发展的探索&#xff08;一&#xff09; 文章目录FPGA护理&#xff1a;跨学科发展的探索&#xff08;二&#xff09;系列文章目录引言三、FPGA 在精神医学护理中的应用…

localforage的数据仓库、实例、storeName和name的概念和区别

在 localForage 中&#xff0c;数据仓库、实例、storeName 和 name 是核心概念&#xff0c;用于管理底层存储&#xff08;IndexedDB/WebSQL/localStorage&#xff09;。以下是详细解释和区别&#xff1a; 1. 数据仓库 (Database) 定义&#xff1a;指底层的物理数据库&#xff…

使用MAS(Microsoft Activation Scripts)永久获得win10专业版和office全套

文章目录Microsoft Activation Scripts简介下载地址使用方法Microsoft Activation Scripts简介 MAS是Microsoft Activation Scripts缩写。 主要提供如下功能&#xff1a; 使用该脚本可以永久获得win10专业版和office全套&#xff08;可选&#xff09; 下载地址 https://pan…

零 shot 语义+在线闭环:深度学习让机器人学会“主动”

来gongzhonghao【图灵学术计算机论文辅导】&#xff0c;快速拿捏更多计算机SCI/CCF发文资讯&#xff5e;在当下&#xff0c;机器人与深度学习的融合正成为AI领域的核心发展趋势&#xff0c;相关研究在顶会顶刊上热度居高不下。从ICLR到CoRL&#xff0c;诸多前沿成果不断涌现&am…

Nginx学习笔记(三)——在 CentOS 7 中配置阿里云镜像源

&#x1f4da; Nginx学习笔记&#xff08;三&#xff09;——在 CentOS 7 中配置阿里云镜像源 在 CentOS 7 中配置阿里云镜像源可显著提升软件安装和更新的速度&#xff0c;以下是详细操作步骤&#xff1a; &#x1f527; 配置阿里云镜像源步骤 1️⃣ 备份原有源配置 sudo mv /…

WebSocket--简单介绍

一、什么是 WebSocket&#xff1f;定义&#xff1a;WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。作用&#xff1a;实现客户端&#xff08;浏览器&#xff09;和服务器之间的实时、双向通信。优势&#xff1a;连接保持&#xff0c;通信实时性强&#xff08;不像 HT…

【STM32 LWIP配置】STM32H723ZG + Ethernet +LWIP 配置 cubemx

STM32H723ZG LAN8742 Ethernet LWIP 配置 cubemx &#x1f31e;这边记录一下这块mcu 配置以太网的过程&#xff0c;IDE是KEIL MDK&#xff0c;其实就是在下面多次提到的blog的基础上 在scatter file进行配置 首先&#xff0c;如果想要简单一点 直接去cubemx 那边获取相关的例…

EI检索-学术会议 | 人工智能、虚拟现实、可视化

第五届人工智能、虚拟现实与可视化国际学术会议&#xff08;AIVRV 2025&#xff09;定于2025年9月5-7日在中国 成都召开。人工智能正驱动各行业智能化转型&#xff0c;提升效率与质量&#xff1b;虚拟现实技术以其沉浸感重塑教育、娱乐、医疗等领域体验&#xff1b;可视化技术…

力扣(H指数)

一、题目分析 &#xff08;一&#xff09;问题描述 给定一个整数数组 citations&#xff0c;其中 citations[i] 表示研究者的第 i 篇论文被引用的次数。我们需要计算并返回该研究者的 H 指数。根据维基百科定义&#xff1a;H 指数代表“高引用次数”&#xff0c;一名科研人员的…

标准io(1)

标准I/O基础概念标准I/O&#xff08;Standard Input/Output&#xff09;是C语言提供的一组高级文件操作函数&#xff0c;位于<stdio.h>头文件中。与低级I/O&#xff08;如Unix的系统调用read/write&#xff09;相比&#xff0c;标准I/O引入了缓冲机制&#xff0c;能显著提…