- 在Kotlin中我们有两种方式来实现反射的功能。一种是调用Java的反射包 java.lang.reflect 下面的API,另外一种就是直接调用Kotlin的kotlin.reflect 包下面的API。不过Kotlin把包的实现放到了单独的kotlin-reflect-1.3.41.jar里面。如果想使用Kotlin反射功能需要在build.gradle中配置以下依赖。当前最高版本是1.3.41
implementation 'org.jetbrains.kotlin:kotlin-reflect:1.3.41'
类引用
首先定义一个代码实例:
open class BaseContainer<T>
class Container<T : Comparable<T>> : BaseContainer<Int> {
var element: MutableList<T>
constructor(element: MutableList<T>) : super() {
this.element = element
}
fun sort(): Container<T> {
element.sort()
return this
}
override fun toString(): String {
return "Container(element = $element)"
}
}
反射是在运行时获取一个类的引用。我们已经知道 ::class 调用可以获取到当前对象的KClass对象
val container = Container(mutableListOf(1, 2, 3, 4, 5))
val kClass = container::class
如果使用java.class对象直接使用javaClass这个扩展属性
val jClass = container.javaClass
其扩展源码如下:
public inline val <T: Any> T.javaClass : Class<T>
@Suppress("UsePropertyAccessSyntax")
get() = (this as java.lang.Object).getClass() as Class<T>
函数引用
有一个简单的判断是否是基数的函数
fun isOdd(x: Int) = x % 2 != 0
调用的时候可以直接在代码中调用
isOdd(7)
isOdd(2)
如果想在高阶函数中把他作为一个参数来使用,可以使用 “::” 操作符。
val nums = listOf(1, 2, 3)
val filter = nums.filter(::isOdd)
println(filter)
输出
[1, 3]
这里的 ::isOdd 就是一个函数类型(Int)->Boolean的值
反编译成java代码是下面,就是去循环调用方法去判断
List nums = CollectionsKt.listOf(new Integer[]{1, 2, 3});
Iterable $receiver$iv = (Iterable)nums;
Collection destination$iv$iv = (Collection)(new ArrayList());
Iterator var5 = $receiver$iv.iterator();
while(var5.hasNext()) {
Object element$iv$iv = var5.next();
int p1 = ((Number)element$iv$iv).intValue();
if (isOdd(p1)) {
destination$iv$iv.add(element$iv$iv);
}
}
List filter = (List)destination$iv$iv;
System.out.println(filter);
属性引用
Kotlin中,访问属性属于第一级对象,可以使用“::”操作符
var a = 1
@JvmStatic
fun main(args: Array<String>) {
println(::a.get())
::a.set(2)
println(a)
}
输出
1
2
表达式 ::a 等价于KProperty的一个属性,它可以允许我们通过get()函数获取值 ::a.get()
对于可变属性var a=1,返回类型为KMutableProperty的值,并且还有set方法::a.set(2)
绑定函数和属性引用
我们可以用一个对象实例的方法。
val digitRegex = "\\d+".toRegex()
println(digitRegex.matches("1"))
println(digitRegex.matches("x"))
println(digitRegex.matches("4"))
在Kotlin中可以直接饮用对象的实例matches()方法
val isDigit = digitRegex::matches
println(isDigit("3"))
println(isDigit("4"))
println(isDigit("x"))