类引用
最基本的反射功能是获取对 Kotlin 类的运行时引用。 要获取对静态已知的 Kotlin 类的引用,可以使用类字面量语法:
1 | val c = MyClass::class |
该引用是 KClass
类型值。
Kotlin 类引用与 Java 类引用不同。 要获取 Java 类引用,请在 KClass 实例上使用 .java
属性。
绑定类引用
可以通过将对象用作接收者来获取对具有相同 ::class
语法的特定对象的类的引用。
属性
simpleName
: 在源代码中声明的类的简单名称,如果该类没有名称(例如,如果它是匿名对象的类),则为 null。qualifiedName
: 类的完全限定的点分隔名称,如果该类是本地类或匿名对象的类,则为 null。members
: 此类中可访问的所有函数和属性,包括此类及其所有超类中声明的函数和属性。 不包括构造函数。constructors
: 此类中声明的所有构造函数。nestedClasses
: 在该类中声明的所有类。 这包括内部和静态嵌套类。objectInstance
: object declaration 的实例,如果此类不是 object declaration,则为 null。isInstance(value: Any?)
: 如果 value 是给定平台上此类的实例,则返回 true。typeParameters
: 该类的类型参数列表。 该列表不包括外部类的类型参数。supertypes
: 此类的直接超类型列表,按照它们在源代码中列出的顺序排列。sealedSubclasses
: 如果此类是 sealed 类,则为直接子类的列表,否则为空列表。visibility
: 此类的可见性,如果其可见性无法在 Kotlin 中表示,则为 null。isFinal
: 如果该类是 final 类,则为 true。isOpen
:isAbstract
:isSealed
:isData
: 如果此类或 object 具有 data 关键字,则为 true。isInner
:isCompanion
: 如果此类是伴生对象,则为 true。isFun
: 如果此类是 Kotlin 函数式接口,则为 true。isValue
: 如果此类是 value 类,则为 true。
Callable 引用
对函数、属性和构造函数的引用也可以作为函数类型的实例来调用或使用。
所有 Callable 引用的公共超类型是 KCallable<out R>
,其中 R
是返回值类型。 它是属性的属性类型,以及构造器的构造类型。
函数引用
可以将函数用作函数类型值,即将它传递给另一个函数。 为此,请使用 ::
运算符:
1 | val numbers = listOf(1, 2, 3) |
这里的 ::isOdd
是函数类型 (Int) -> Boolean
的值。
函数引用属于 KFunction<out R>
子类型之一,具体取决于参数计数。 例如,KFunction3<T1, T2, T3, R>
。
当从上下文中知道预期类型时,::
可以与重载函数一起使用。
如果需要使用类的成员或者扩展函数,需要限定:String::toCharArray
。
即使使用对扩展函数的引用来初始化变量,推断的函数类型也不会有接收者,但它会有一个额外的参数来接受接收者对象。 要改为使用带有接收者的函数类型,请显式指定类型.
属性引用
要在 Kotlin 中将属性作为一流对象访问,请使用 ::
运算符
表达式 ::x
的计算结果为 KProperty<Int>
类型的属性对象。 可以使用 get()
读取其值或使用 name
属性检索属性名称。
对于可变属性,例如 var y = 1
,::y
返回一个具有 KMutableProperty<Int>
类型的值,该类型具有 set()
方法:
可以在需要具有单个泛型参数的函数的地方使用属性引用
与 Java 反射的互操作性
标准库包含反射类的扩展,这些扩展提供了与 Java 反射对象之间的映射(请参阅包 kotlin.reflect.jvm)。 例如,查找用作 Kotlin 属性的 getter 的支持字段或 Java 方法
构造器引用
构造函数可以像方法和属性一样被引用。 可以在程序需要函数类型对象的任何地方使用它们,该对象采用与构造函数相同的参数并返回适当类型的对象。
通过使用 ::
运算符并添加类名来引用构造函数。 考虑以下函数,它需要一个没有参数且返回类型为 Foo 的函数参数
根据参数计数,对构造函数的可调用引用被类型化为 KFunction<out R>
子类型之一。