- Kotlin进阶实战
- 沈哲 易庞宙编著
- 702字
- 2025-02-20 21:22:45
7.3.3 函数引用,获取类的成员函数
1.Java获取类的成员函数
Java获取类的成员函数对应的是java.lang.reflect.Method,有以下5种方式:
//根据函数名name、参数parameterTypes获取类自身的public的函数(包括从基类继承的、从接 口实现的所有public函数) public Method getMethod(String name, Class[] parameterTypes) //获取全部public的函数(包括从基类继承的、从接口实现的所有public函数) public Method[] getMethods() //根据函数名name、参数parameterTypes获取类自身声明的函数,包含 public、protected和 private方法 public Method getDeclaredMethod(String name, Class[] parameterTypes) //获取类自身声明的函数,包含 public、protected和private方法 public Method[] getDeclaredMethods() //如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回Method 对象,它表示底层类的立 即封闭方法。若不存在,则返回null public Method getEnclosingMethod()
2.Kotlin获取类的成员函数
Kotlin通过反射调用函数,需要KFunction实例。KFunction实例可以通过两种方式获得:一种是方法引用,另一种是通过KClass提供的API获得。
在3.2节曾经介绍过Kotlin和Java的方法引用,方法引用是简化版本的Lambda表达式,它和Lambda表达式拥有相同的特性。
Kotlin和Java的方法引用使用::操作符,Kotlin除了可以引用类中的成员函数、扩展函数外,还可以引用顶层(top-level)函数。
方法引用属于KFunction的子类型KFunctionN,N代表具体的参数数量,例如KFunction2<T1, T2,R>。KFunction与Lambda的Function类似,都可以通过invoke()方法调用该引用函数。
例如:

执行结果如下:
8 8 8
KFunctionN类型属于合成的编译器生成类型,我们无法在包kotlin.reflect中找到它们的声明。
在上述例子中,最后一行代码为:
println(sunFunc.call(3, 5))
其实这里调用了KCallable接口的call()方法。

对于KFunction对象,也可以使用KCallable的call()方法来调用被引用的函数。call()方法使用指定的参数列表,开发者需要自行匹配所使用的实参类型和数量,如果其类型与参数的类型不匹配,就会引发异常。
而KFunctionN的invoke()方法的形参类型和返回值类型是可以确定的,调用它的invoke()时编译器会帮我们做检查。
当然,也可以使用KFunctionN来引用类的扩展函数。引用扩展函数的用法跟引用成员函数的用法是一致的。
