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来引用类的扩展函数。引用扩展函数的用法跟引用成员函数的用法是一致的。