在学习 Java反射 的过程中,注意到Class类 有 以下四个方法:
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
public Method[] getMethods() throws SecurityException
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
public Method[] getDeclaredMethods() throws SecurityException
通过查阅资料学习了各个方法的作用、及相互之间的区别,在此进行整理记录,如有错误之处,还请指正。
getMethod
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
返回一个 Method 对象,它反映当前 Class 对象所表示的类或接口中指定name的
公共(public)
成员方法(包括父类继承的、接口实现的、父接口继承的)。
name 参数用于指定所反映的方法的名称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。如果 parameterTypes 为 null,则按空数组处理。
BUT:如果 name 是 “< init >;” 或 “< clinit >”,则将引发 NoSuchMethodException。
要反映的方法由下面的算法匹配确定(设 C 为当前Class对象所表示的类):
1. 在 C 中搜索任一匹配的方法。如果找不到匹配的方法,则将在 C 的超类上递归调用第 1 步算法。
2. 如果在第 1 步中没有找到任何方法,则在 C 的超接口中搜索匹配的方法。如果找到了这样的方法,则反映该方法。
在C 中查找匹配方法的规则:如果 C 正好声明了一个具有指定名称的公共方法并且恰恰有相同的形参类型,则它就是反映的方法。如果在 C 中找到了多个这样的方法,并且其中有一个方法的返回类型比其他方法的返回类型都特殊,则反映该方法;否则将从中任选一个方法。
注意:类中可能有多个匹配方法,因为尽管 Java 语言禁止类声明带有相同方法签名(方法名+参数列表)但不同返回类型的多个方法,但 Java 虚拟机并不禁止。这增加了虚拟机的灵活性,可以用来实现各种语言特性。例如,可以使用桥方法 (brige method)实现协变返回;桥方法以及将被重写的方法将具有相同的签名,不同的返回类型。
如果当前Class对象 代表着数组类型,那么getMethod方法不会查找clone()方法。
getMethod可以获取当前Class 对象所代表的类中的 静态方法(包括从超类继承的静态方法)
Java8新增:
Static methods declared in superinterfaces of the class or interface represented by this Class object are not considered members of the class or interface.
getMethods
public Method[] getMethods() throws SecurityException
返回一个Method对象的数组,这些Method对象反映当前 Class 对象所表示的类或接口的
公共
member 方法。(包括那些由该类或接口声明的以及从超类和超接口继承的方法)
如果当前Class对象代表数组类型,则getMethods 返回从 Object 类继承的所有(公共)member 方法的Method对象。但不包括clone()方法的Method对象。
如果此 Class 对象表示一个没有公共成员方法的类或接口(包括从超类、超接口 继承实现的方法),则此方法返回长度为 0 的Method数组。(但一个类永远都会有公有方法,从Object继承的)
如果当前Class 对象表示一个基本类型或 void,则此方法返回长度为 0 的Method数组。
类初始化方法 < clinit > 不包含在返回的Method数组中
当前Class对象所代表的类中 的静态方法(包括从父类继承的静态方法)也会被包含在返回的Method数组中
If this Class object represents a type that has multiple public methods with the same name and parameter types, but different return types, then the returned array has a Method object for each such method.
Static methods declared in superinterfaces of the class or interface represented by this Class object are not considered members of the class or interface.
返回的Method数组中的元素没有排序,也没有任何特定的顺序。
getDeclaredMethod
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException
返回一个 Method 对象,该对象反映当前 Class 对象所表示的类或接口中name指定的已声明方法(包括private修饰的方法。该方法必须在当前类或接口中有声明,如 抽象方法的实现。如果当前类中 某一方法继承自父类,但该类中并未对其重写(也就是说,该类中不存在这个方法的声明),则调用getDeclaredMethod将会抛出NoSuchMethodException)。
参数:
name 指定方法名
parameterTypes 是 Class 对象的一个数组,它按声明顺序标识该方法的形参类型。
如果在某个类中声明了带有相同参数类型的多个方法,并且其中有一个方法的返回类型比其他方法的返回类型都特殊,则返回该方法;否则将从中任选一个方法。
如果name是 “< init >” 或 “< clinit >”,则引发一个 NoSuchMethodException。
getDeclaredMethods
返回一个 Method 对象数组,这些Method对象反映当前 Class 对象表示的类或接口声明的所有方法,包括public、protected、缺省 和 private 方法,但不包括未声明的方法(如 继承 但未重写的方法 )。
If this Class object represents a type that has multiple declared methods with the same name and parameter types, but different return types, then the returned array has a Method object for each such method.
类初始化方法 < clinit > 不包含在返回的Method数组中。
如果该类或接口未声明任何方法,或者此 Class 对象 表示一个基本类型、一个数组类型 或 void,则此方法返回一个长度为 0 的Method数组。
返回Method数组中的元素没有排序,也没有任何特定的顺序。
简单总结:
-
getMethod : 能获取当前Class对象表示的类中 一个指定 方法名的 公有方法 的Method对象 (包括继承的)。
-
getMethods : 能获取当前Class对象表示的类中 所有的 公有方法 的Method 对象 (包括继承的)。
-
getDeclaredMethod : 能获取当前Class对象表示的类中 一个指定 方法名的,并且在该类中存在声明的方法 的Method对象。(无视访问修饰符)
-
getDeclaredMethods : 能获取当前Class对象表示的类中 所有存在声明的方法 的Method对象。(无视访问修饰符)
-
但要注意 数组、基本类型、void、< init >、< clinit > 几个特例。