详解kotlin中::双冒号的使用
作者:不入流Android开发 发布时间:2022-09-04 10:17:23
一、:: 双冒号操作符
在 Kotlin 中 , :: 双冒号操作符 的作用是 获取 类 , 对象 , 函数 , 属性 的 类型对象 引用 ;
获取的这些引用 , 并不常用 , 都是在 Kotlin 反射操作时才会用到 ;
相当于 Java 中的 反射 类的 字节码类型 Class 类型 , 对象的类型 Class 类型 , 对象的函数 Method 类型 , 对象的属性字段 Field 类型 ;
1、获取类的引用
在 Kotlin 中 , 使用 :: 双冒号操作符 获取 类的类型对象引用 代码格式为 :
Java或Kotlin类名::class
获取的 Kotlin 类 的 类型对象 的类型 为 KClass<类名> , 如 : 获取 String 字符串类型的引用 , 代码为 :
String::class
获取的 String 类的引用类型 为 KClass ,
代码示例 : 下面的代码中 , 通过 Student::class 获取的 引用对象的类型 是 KClass ;
import kotlin.reflect.KClass
class Student {
var name = "Tom"
var age = 18
fun info() {
println("$name is $age years old")
}
}
fun main() {
val studentClassRef: KClass<Student> = Student::class
}
引用类型 KClass 说明
Kotlin 中 类的引用类型 KClass 中 提供了很多有用的属性 , 如 :
public actual val simpleName: String? 属性可以获取类的简单名称 ;
public val qualifiedName: String? 属性可以获取类的完整名称 ;
kotlin.reflect.KClass 是 Kotlin 语言中的字节码类 , java.lang.Class 是 Java 语言的字节码类 ;
下面是 KClass 的原型 , 省略了后面的代码 ;
package kotlin.reflect
/**
* 表示一个类并提供内省功能。
* 此类的实例可通过 `::class` 语法获得。
* 更多信息请参见
* [Kotlin 语言文档]
* (https://kotlinlang.org/docs/reference/reflection.html#class-references)。
*
* @param T 类的类型。
*/
public actual interface KClass<T : Any> : KDeclarationContainer, KAnnotatedElement, KClassifier {
/**
* 类在源代码中声明的简单名称,
* 如果该类没有名称(例如,它是一个匿名对象文字),
* 则为 `null`。
*/
public actual val simpleName: String?
/**
* 类的全限定名称,以点分隔符分隔,
* 如果该类是本地类或匿名对象文字,则为 `null`。
*/
public val qualifiedName: String?
}
2、获取对象类型的引用
在 Kotlin 中 , 使用 :: 双冒号操作符 获取 对象类型的引用 代码格式为 :
Java或Kotlin实例对象::class
获取的 对象类型的引用 的类型 为 KClass<out 类名> , 如 : 获取 String 字符串类型的引用 , 代码为 :
"Tom"::class
获取的 String 对象类型的引用 类型 为 KClass ,
在某种程度上 , 可以理解为 类的引用 等同于 对象的引用 ;
代码示例 : 下面的代码中 , 通过 var student: Student = Student() 实例对象 , 获取的 引用对象类型的类型 是 KClass ;
import kotlin.reflect.KClass
class Student {
var name = "Tom"
var age = 18
fun info() {
println("$name is $age years old")
}
}
fun main() {
var student: Student = Student()
val studentObjectRef: KClass<out Student> = student::class
}
3、获取函数的引用
调用 类名::函数名 获取的 函数类型 引用 , 其类型是函数类型的 , 如下代码中 ,
调用 Student::info 获取的函数类型变量 的 类型为 (Student) -> Unit , 该函数引用 可以直接调用 invoke 函数执行对应的 被引用函数 ;
class Student {
var name = "Tom"
var age = 18
fun info() {
println("$name is $age years old")
}
}
fun main() {
var student: Student = Student()
var studentInfo: (Student) -> Unit = Student::info
studentInfo.invoke(student)
}
执行结果如下 :
4、获取属性的引用
如下代码中 , 使用 Student::name 代码 , 获取 Student 类的 name 属性类型为 KMutableProperty1<Student, String> , 获取到该 name 属性的引用 , 相当于 Java 反射中的 Field 对象 , 调用 KMutableProperty1#get 函数 传入 Student 实例对象 , 可以获取该实例对象的 name 属性 ;
import kotlin.reflect.KMutableProperty1
class Student {
var name = "Tom"
var age = 18
fun info() {
println("$name is $age years old")
}
}
fun main() {
var student: Student = Student()
var studentName: KMutableProperty1<Student, String> = Student::name
println(studentName.get(student))
}
二、 java.lang.Class 与 kotlin.reflect.KClass
KClass 是 Kotlin 类的 引用类型 , 是 Kotlin 类的实例对象 , 通过 类名::class 可以获取 KClass 引用 ;
KClass 提供了关于 Kotlin 类的一系列功能 , 包括 :
获取类的简单名称
获取类的完整名称
创建类的实例对象
获取类的成员字段和方法
获取类的继承关系
KClass 的全类名是 kotlin.reflect.KClass , Class 的全类名是 java.lang.Class ;
与 KClass 相对的是 Java 中的 Class 类 , 是 Java 中的 类的 引用类型 ;
在 Java 语言中 , 需要通过 类名.class 获取 Class 实例对象 ;
在 Kotlin 语言中 , 需要通过类名::class.java 获取 Class 实例对象 ;
Class 提供了关于 Java 类的一系列功能 , 包括 :
获取类的 注解
获取类的 继承关系
获取类的 成员字段和方法
代码示例 :
import kotlin.reflect.KClass
import kotlin.reflect.KProperty0
import kotlin.reflect.KProperty1
class Student {
var name = "Tom"
var age = 18
fun info() {
println("$name is $age years old")
}
}
fun main() {
// Student 实例对象
var student: Student = Student()
// kotlin.reflect.KClass
var kClazz: KClass<Student> = Student::class
// kotlin.reflect.KClass
var studentClazz: KClass<out Student> = student::class
// java.lang.Class
var javaClass: Class<Student> = Student::class.java
// java.lang.Class
var studentJavaClazz: Class<out Student> = student::class.java
// KProperty1<Student, Class<Student>>
var javaClass2: KProperty1<Student, Class<Student>> = Student::javaClass
// KProperty0<Class<Student>>
var studentJavaClass2: KProperty0<Class<Student>> = student::javaClass
来源:https://blog.csdn.net/m0_70749039/article/details/130069877
猜你喜欢
- 在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应。解决的方法就是新开一个线程,把耗时的
- System.Web.Caching.Cache Insert和Add方法的区别Add()object Add(string key, ob
- 一、循环结构循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适
- Android Studio连接手机设备教程,供大家参考,具体内容如下一、ADB环境配置1.查看自己Android Studio配置的sdk
- 不想废话,直接写了!因为是留给自己做随笔的,所以大神们看到别喷…… 1.必须有微信公众账号 2.你也可以申请测试微信号,
- 前言Java中URL传中文时乱码的问题相信不少朋友都遇到过,最近就遇到一个问题,就是在Action当中把一条中文信息绑定在URL的后面,Ac
- 数组与链表的比较:数组通过下标访问的话是O(1)数组一旦声明 长度就是固定的数组的数据是物理逻辑均连续的链表增删要快一些, 数组遍历快一些长
- 目录1、需求2、问题2、获取1)导入依赖为了获取客户端类型、操作系统类型、ip、port2)封装获取body字符串的工具类3) * 类4)继
- Google在2015的IO大会上,给我们带来了更加详细的Material Design设计规范,同时,也给我们带来了全新的Android
- 一.线程不安全多线程的执行环境中,程序的执行结果和预期的结果不符合,这就称为发生了线程不安全现象二.那些情况导致了线程不安全?大致分为以下5
- 本文实例讲述了java实现新浪微博Oauth接口发送图片和文字的方法。分享给大家供大家参考。具体如下:基于网上很多人利用新浪api开发新浪微
- 一、redis发布订阅简介Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收信息。可以参
- 页面拖动到最后一页 再向下滑动回复到 第一页,第一页向前滑动回到 最后一页同时,底部红色小圆点随着页面的滑动距离比例随时改变位置布局:<
- 跨域配置如下,Springboot 版本为 2.4.1///跨域访问配置@Configurationpublic class CorsCon
- 本文实例为大家分享了Java实现置换密码加密解密,供大家参考,具体内容如下思路置换密码只不过是简单的换位而已,这里写的是一个分组长度为7的置
- 方法一、使用系统控件ViewFlipper方式:布局文件:<ViewFlipper andro
- 简介同步容器主要分两类,一种是Vector这样的普通类,一种是通过Collections的工厂方法创建的内部类虽然很多人都对同步容器的性能低
- 前言:Android的服务是开发Android应用程序的重要组成部分。不同于活动Activity,服务是在后台运行,服务没有接口,生命周期也
- 利用Java语言中的集合、Swing、线程等知识点编写一个坦克大战游戏。(1) 画出敌我坦克的原理:在坦克类里面有一个布尔类型变量good。
- 建议缓存放到 service 层,你可以自定义自己的 BaseServiceImpl 重写注解父类方法,继承自己的实现。为了方便,这里我们将