概述

每个方法都由修饰符返回值参数注解抛出的异常组成。而java.lang.reflect.Method类提供了获取上述内容的API。

需要注意的是,反射一个类的方法时不会考虑父类的方法,只会反射当前类的方法。继承的方法也无法被反射。

获取Method

获取Method类对象的方法如下,需要通过Class类对象来调用下面的方法:

成员方法 说明
Method getMethod(String name, Class<?>... parameterTypes) 根据方法名称和相关参数,来定位需要查找的Method对象并返回,包括由类或接口声明的方法以及从超类和超接口继承的方法。但注意,只能获取由public修饰的方法。
Method[] getMethods() 返回一个包含Method对象的数组,这些对象反映了此Class对象表示的类或接口的所有公共方法,包括由类或接口声明的方法以及从超类和超接口继承的方法。但注意,只能获取由public修饰的方法。
Method getDeclaredMethod(String name, Class<?>... parameterTypes) 根据方法名称和相关参数,来定位需要查找的Method对象并返回,可以获取那些public、private、protected等修饰的方法。但不能获取超类、超接口中的任何方法。
Method[] getDeclaredMethods() 返回一个包含Method对象的数组,该对象反映了此Class对象表示的类或接口的所有声明方法,包括公共(public)、受保护(protected)、默认(包)访问和私有(private)方法,但不包括继承的方法。但不能获取超类、超接口中的任何方法。
Method getEnclosingMethod() 如果此Class对象表示方法内的本地类或匿名类,则返回一个Method对象,表示底层类的直接封闭方法。 否则返回null 。

上述方法的实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();// 根据方法名称和相关参数,来定位需要查找的Method对象并返回,包括由类或接口声明的方法以及从超类和超接口继承的方法。Method method = aClass.getMethod("print", String.class);// 获取本类中的方法Method printSon = aClass.getMethod("printSon");// 获取父类中的方法Method reprint = aClass.getMethod("reprint");// 获取接口中的方法// 返回一个包含Method对象的数组,这些对象反映了此Class对象表示的类或接口的所有公共方法,包括由类或接口声明的方法以及从超类和超接口继承的方法。Method[] methods = aClass.getMethods();// 获取本类、超类、超接口中的所有方法for (Method m : methods) {System.out.println(m.getName());}System.out.println("====================================================");// 根据方法名称和相关参数,来定位需要查找的Method对象并返回,可以获取那些privateer、protected等修饰的方法。Method privatePrint = aClass.getDeclaredMethod("privatePrint", String.class);Method printSon2 = aClass.getDeclaredMethod("printSon");// 返回一个包含Method对象的数组,该对象反映了此Class对象表示的类或接口的所有声明方法,包括公共、受保护、默认(包)访问和私有方法,但不包括继承的方法。但不能获取超类、超接口中的任何方法。Method[] declaredMethods = aClass.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod.getName());}System.out.println("====================================================");// 如果此Class对象表示方法内的本地类或匿名类,则返回一个Method对象,表示底层类的直接封闭方法。 否则返回null 。Method enclosingMethod = son.getRunnable().getClass().getEnclosingMethod();// 匿名内部类Method enclosingMethod2 = son.innerClassMethod().getClass().getEnclosingMethod();}
}interface MyInterface {// 接口中public修饰的方法public void reprint();// 接口中的默认方法default void defaultMethod() {System.out.println("ddd");}
}class Father implements MyInterface {// 父类中的无参无返回值的public方法public void print() {System.out.println("Hello World!");}// 父类中的带参带返回值的public方法public boolean print(String msg) {if (msg == null) {return false;}System.out.println(msg);return true;}// 实现接口中的方法@Overridepublic void reprint() {System.out.println("reprint...");}// 父类中被private修饰的方法private void hello() {System.out.println("私有方法");}
}class Son extends Father {// 子类中public修饰的无参无返回值方法public void printSon() {System.out.println("Son...");}// 子类中protected修饰的带参无返回值方法protected void privatePrint(String msg) {System.out.println("私生子..." + msg);}// 子类中方法内有本地类,并且将本地类对象返回的方法public Object innerClassMethod() {class InnerClass {}return new InnerClass();}// 子类中使用了匿名内部类的方法public Runnable getRunnable() {return new Runnable() {@Overridepublic void run() {System.out.println("run...");}};}
}/*打印结果:printSoninnerClassMethodgetRunnablereprintprintprintwaitwaitwaitequalstoStringhashCodegetClassnotifynotifyAlldefaultMethod====================================================printSonprivatePrintinnerClassMethodgetRunnable====================================================*/

常用方法

我们知道每个方法都由修饰符、返回值、参数、注解和抛出的异常组成。所以下面的方法是对这些的获取。

获取修饰符

方法可以被以下修饰符修饰:

  • 访问权限控制符:public, protected, private
  • 静态修饰符:static
  • 不允许修改的:final
  • 抽象方法:abstract
  • 同步锁:synchronized
  • 本地方法:native
  • 严格的浮点型强度:strictfp
  • 注解
成员方法 说明
int getModifiers() 返回该Method对象所表示方法的修饰符。但返回的是一个整数,所以需要通过Modifier.toString()方法转换成字符串。

该方法的实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getMethods();for (Method method : methods) {// 获取方法的修饰符,但返回的是一个整数,所以需要通过Modifier.toString()方法转换成字符串int modifiers = method.getModifiers();System.out.println("方法名:" + method.getName() + ", 修饰符:" + Modifier.toString(modifiers));}}
}interface MyInterface {// 接口中public修饰的方法public abstract void reprint();// 接口中的默认方法default void defaultMethod() {System.out.println("ddd");}
}class Father implements MyInterface {// 父类中的无参无返回值的public方法public void print() {System.out.println("Hello World!");}// 父类中的带参带返回值的public方法public boolean print(String msg) {if (msg == null) {return false;}System.out.println(msg);return true;}// 实现接口中的方法@Overridepublic void reprint() {System.out.println("reprint...");}// 父类中被private修饰的方法private void hello() {System.out.println("私有方法");}
}class Son extends Father {// 子类中public修饰的无参无返回值方法public void printSon() {System.out.println("Son...");}// 子类中protected修饰的带参无返回值方法protected void privatePrint(String msg) {System.out.println("私生子..." + msg);}// 子类中方法内有本地类,并且将本地类对象返回的方法public Object innerClassMethod() {class InnerClass {}return new InnerClass();}// 子类中使用了匿名内部类的方法public Runnable getRunnable() {return new Runnable() {@Overridepublic void run() {System.out.println("run...");}};}public final static synchronized native void test();
}/*打印结果:方法名:test, 修饰符:public static final synchronized native方法名:printSon, 修饰符:public方法名:innerClassMethod, 修饰符:public方法名:getRunnable, 修饰符:public方法名:print, 修饰符:public方法名:print, 修饰符:public方法名:reprint, 修饰符:public方法名:wait, 修饰符:public final方法名:wait, 修饰符:public final方法名:wait, 修饰符:public final native方法名:equals, 修饰符:public方法名:toString, 修饰符:public方法名:hashCode, 修饰符:public native方法名:getClass, 修饰符:public final native方法名:notify, 修饰符:public final native方法名:notifyAll, 修饰符:public final native方法名:defaultMethod, 修饰符:public*/

获取返回值类型

可以获取返回值类型的两个方法如下:

成员方法 说明
Class<?> getReturnType() 返回一个Class对象,该对象表示此Method对象表示的方法的正式返回类型。
Type getGenericReturnType() 返回一个Type对象,该对象表示此Method对象表示的方法的正式返回类型。如果返回类型是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。注:如果返回值类型不是泛型,那么两个方法的返回值是一致的;如果是泛型,getGenericReturnType()方法会返回泛型的类型。

实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 获取返回值类型// getReturnType(),返回一个Class对象,该对象表示此Method对象表示的方法的正式返回类型。// getGenericReturnType(),返回一个Type对象,该对象表示此Method对象表示的方法的正式返回类型。如果返回类型是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。// 注:如果不是泛型,那么两个方法的返回值是一致的;如果是泛型,getGenericReturnType()方法会返回泛型的类型Class<?> returnType = method.getReturnType();Type genericReturnType = method.getGenericReturnType();System.out.println(returnType + ", " + genericReturnType);}}
}class Son {// 基本数据类型的返回值public int getInt() {return 1;}// 包装类型的返回值public Boolean getBoolean() {return Boolean.TRUE;}// 引用数据类型的返回值public String getString() {return "xxx";}// 引用数据类型的返回值public Test getTest() {return new Test();}// 泛型数据类型的返回值public List<String> getList() {return new ArrayList<>();}// 泛型数据类型的返回值public Map<String, Object> getMap() {return new HashMap<>();}
}/*打印结果:class java.lang.Boolean, class java.lang.Booleanint, intinterface java.util.Map, java.util.Map<java.lang.String, java.lang.Object>class java.lang.String, class java.lang.Stringinterface java.util.List, java.util.List<java.lang.String>class com.demo.bean.demo.Test, class com.demo.bean.demo.Test*/

获取参数类型

获取方法参数相关的方法如下:

成员方法 说明
int getParameterCount() 获取该Method对象所表示方法的参数数量。
Parameter[] getParameters() 返回一个Parameter对象数组,表示该Method对象所表示方法的所有参数。
Class<?>[] getParameterTypes() 获取该Method对象所表示方法的所有参数类型的数组。
Type[] getGenericParameterTypes() 获取该Method对象所表示方法的所有参数类型的数组,一般情况下,同getParameterTypes()方法的返回值一样,如果存在泛型,则该方法会返回泛型的类型。

对应的实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 获取该方法的参数数量int parameterCount = method.getParameterCount();// 获取该方法的参数数组Parameter[] parameters = method.getParameters();// 获取参数类型数组,getParameterTypes()和getGenericParameterTypes()方法都可以获取,一般情况下返回值类型一样,只有在泛型的情况有些不同Class<?>[] parameterTypes = method.getParameterTypes();Type[] genericParameterTypes = method.getGenericParameterTypes();for (int i = 0; i < parameterTypes.length; i++) {System.out.print("方法名:" + method.getName() + ", 参数类型:" + parameterTypes[i].getTypeName() + ", " + genericParameterTypes[i].getTypeName() + "\t");}System.out.println();}}
}class Son {public void m1(int i) {}public void m2(Boolean bool) {}public void m3(String str, int i) {}public void m4(List<String> list) {}public void m5(Integer... nums) {}
}/*打印结果:方法名:m1, 参数类型:int, int方法名:m3, 参数类型:java.lang.String, java.lang.String 方法名:m3, 参数类型:int, int方法名:m4, 参数类型:java.util.List, java.util.List<java.lang.String>方法名:m2, 参数类型:java.lang.Boolean, java.lang.Boolean方法名:m5, 参数类型:java.lang.Integer[], java.lang.Integer[]*/

获取抛出异常类型

获取抛出异常类型的方法如下:

成员方法 说明
Class<?>[] getExceptionTypes() 返回该Method对象所表示方法通过throws子句抛出的异常类型数组,是Class类型的。
Type[] getGenericExceptionTypes() 返回该Method对象所表示方法通过throws子句抛出的异常类型数组,是Type类型的。如果没有抛出任何异常,则返回一个长度为0的数组。

实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 获取异常类型// getExceptionTypes(),返回该Method对象所表示方法通过throws子句抛出的异常类型数组,是Class类型的// getGenericExceptionTypes(),返回该Method对象所表示方法通过throws子句抛出的异常类型数组,是Type类型的Class<?>[] exceptionTypes = method.getExceptionTypes();Type[] genericExceptionTypes = method.getGenericExceptionTypes();for (int i = 0; i < exceptionTypes.length; i++) {System.out.println("方法名:" + method.getName() + "; 异常类型:" + exceptionTypes[i] + ", " + genericExceptionTypes[i]);}}}
}class Son {public void m1(int i) throws NullPointerException {}public void m2(Boolean bool) throws IllegalArgumentException {}public void m3(String str, int i) throws DateTimeParseException {}public void m4(List<String> list) throws IOException {}public void m5(Integer... nums) throws Exception {}
}/*打印结果:方法名:m3; 异常类型:class java.time.format.DateTimeParseException, class java.time.format.DateTimeParseException方法名:m2; 异常类型:class java.lang.IllegalArgumentException, class java.lang.IllegalArgumentException方法名:m1; 异常类型:class java.lang.NullPointerException, class java.lang.NullPointerException方法名:m4; 异常类型:class java.io.IOException, class java.io.IOException方法名:m5; 异常类型:class java.lang.Exception, class java.lang.Exception*/

获取方法上的注解

方法如下:

成员方法 说明
Annotation[] getAnnotations() 获取该Method对象所表示方法上的所有注解。
<T extends Annotation> T getAnnotation(Class<T> annotationClass) 获取该Method对象所表示方法上指定注解类,如果该方法上存在该注解则返回该注解类,否则返回null。
Annotation[] getDeclaredAnnotations() 返回直接存在该Method对象所表示方法上的所有注解,但会忽略掉继承的注解。如果该方法上没有直接存在的注解,则返回值是一个长度为0的数组。
<T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) 返回直接存在该Method对象所表示方法上的指定类注解,但会忽略掉继承的注解。如果该方法上没有直接存在的注解,则返回值是一个长度为0的数组。
<T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) 如果该方法对象存在指定类型的注解,则返回该注解数组,否则返回 null。只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同。getAnnotationsByType() 方法与 getAnnotation() 方法的区别在于:getAnnotationsByType() 方法会检查修饰该方法对象的注解是否为可重复类型注解,如果是则会返回修饰该方法对象的一个或多个注解。@Repeatable 用于声明注解为可重复类型注解。当声明为可重复类型注解后,如果方法注解仍为一个,则 getAnnotation() 方法会正常返回,如果方法注解为多个,则 getAnnotation() 方法会返回 null。
<T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) 如果该方法对象存在指定类型的注解,则返回该注解数组,否则返回 null。只有类级别的注解会被继承得到,对于其他对象而言,getAnnotationsByType() 方法与 getDeclaredAnnotationsByType() 方法作用相同。

实例如下:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 获取注解Annotation[] annotations = method.getDeclaredAnnotations();for (Annotation annotation : annotations) {System.out.print("方法名:" + method.getName() + "; 注解类型:" + annotation);}System.out.println();// 获取某个注解类
//            AnnotationMethod annotation = method.getAnnotation(AnnotationMethod.class);
//            System.out.println(annotation);}}
}class Son {@Deprecatedpublic void m1() {}@AnnotationMethod()public void m2() {}@AnnotationMethod(name = "xxx")public void m3() {}@AnnotationMethod(name = "xxx", nums = {1, 2, 3, 4})public void m4() {}@AnnotationMethod(nums = {1, 2, 3, 4})private void m5() {}@Cpublic void m6() {}
}@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {METHOD, TYPE})
@interface A {
}@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {METHOD, TYPE})
@interface B {
}@Inherited
@A
@B
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {METHOD, TYPE})
@interface C {
}@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {METHOD})
@Inherited
@interface AnnotationMethod {String name() default "";int[] nums() default {};
}/*打印结果:方法名:m1; 注解类型:@java.lang.Deprecated()方法名:m2; 注解类型:@com.demo.bean.demo.AnnotationMethod(name=, nums=[])方法名:m3; 注解类型:@com.demo.bean.demo.AnnotationMethod(name=xxx, nums=[])方法名:m4; 注解类型:@com.demo.bean.demo.AnnotationMethod(name=xxx, nums=[1, 2, 3, 4])方法名:m6; 注解类型:@com.demo.bean.demo.C()方法名:m5; 注解类型:@com.demo.bean.demo.AnnotationMethod(name=, nums=[1, 2, 3, 4])*/

其他方法

成员方法 说明
String getName() 返回由此Method对象表示的方法的名称,作为String 。
Object invoke(Object obj, Object... args) 执行方法,可以传递参数,返回值就是执行该方法后的返回值。
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果该方法对象上有指定类型的注解,则返回 true,否则为 false。
boolean isVarArgs() 如果该方法对象的参数中存在 可变参数(例如String...args),则返回 true,否则为 false。
Object getDefaultValue() 返回该注解方法对象表示的成员默认值。如果成员属于基本数据类型,则返回对应的包装类实例。如果没有默认值或者该方法实例不表示注解方法,则返回 null。
String toString() 返回该方法对象的字符串表示形式 (擦除泛型)。
String toGenericString() 返回该方法对象的字符串表示形式 (保留泛型)。
boolean isAccessible() 获取该方法对象Method的可访问标志。
void setAccessible(boolean flag) 设置该方法对象的可访问标志。在其他类里调用该方法对象时,如果该方法为私有方法,需要设置访问标志为 true,否则会报异常。
boolean isDefault() 判断该方法对象是否为默认方法,如果是则返回 true,否则为 false。默认方法即是使用default关键字修饰的方法。
boolean isSynthetic() 判断该方法对象是否为合成方法,如果是则返回 true,否则为 false。比如在内部类 中,有一个私有属性,而我们在外部类中,直接引用了这个属性,那么编译器会生成一个合成方法,用于绕开 private 私有属性的限制。
boolean isBridge() 判断该方法对象是否桥接方法,如果是则返回 true,否则为 false。桥接方法是 JDK1.5 引入泛型后,为了使 Java 的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法。

实例:

public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {Son son = new Son();Class<? extends Son> aClass = son.getClass();Method[] methods = aClass.getDeclaredMethods();for (Method method : methods) {// 获取方法名System.out.println("方法名:" + method.getName());if (method.getParameterCount() == 0) {// 调用执行方法method.invoke(son);} else if (method.getParameterCount() == 1) {method.invoke(son, "我是传入的参数");} else if (method.getParameterCount() == 2) {Object returnValue = method.invoke(son, "我是第一个参数", "我是第二个参数");System.out.println(returnValue);}System.out.println("================================");}}
}class Son {public void hello() {System.out.println("Hello World!");}public void hello(String msg) {System.out.println(msg);}public String hello(String str1, String str2) {return str1 + "," + str2;}
}/*打印结果:方法名:hello我是第一个参数,我是第二个参数================================方法名:helloHello World!================================方法名:hello我是传入的参数================================*/

参考链接:

  • 深入理解 Java 反射:Method (成员方法)
  • Class -- 10 -- Method类常用方法解析

Method类的使用相关推荐

  1. java学习(175):method类反射机制

    //class反射编程 //定义一个学生类 public class test124 {public String name;protected int age;double height;priva ...

  2. method java_解析Java中的Field类和Method类

    Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特 ...

  3. java method field_java_解析Java中的Field类和Method类,Field类 Field类中定义了一些方 - phpStudy...

    解析Java中的Field类和Method类 Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够 ...

  4. java-反射-Method类走读

    背景 之前走读了Class类的函数,能让我们更灵活的获取一个类中的信息.然而仅有类信息还是不够的,想要达到灵活调用类中函数的功能还需要借助于reflect包的Method类,本博文将走读Method类 ...

  5. Class -- 10 -- Method类常用方法解析

    原文链接:Class – 10 – Method类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...

  6. Java Method类简介说明

    转自: Java Method类简介说明 下文笔者将讲述Java中Method类的功能简介说明,如下所示: Method类是java.lang.reflect包下Method类被聚合在Class的对象 ...

  7. java反射中method类中的invoke方法是做什么的,他有什么作用?

    就是调用类中的方法,最简单的用法是可以把方法参数化 invoke(class, method) 比如你Test类里有一系列名字相似的方法setValue1.setValue2等等 可以把方法名存进数组 ...

  8. Java反射Filed、Method、Constructor类_02

    文章目录 1. Field类 1.2. Field类常用方法 2. Method类 2.1. Method类常用方法 3. Constructor类 3.1. Constructor类常用方法 4.J ...

  9. Java反射02--Filed,Method,Constructor类

    Java反射02–Filed,Method,Constructor类 一Filed类常用方法 上一篇已经说过了Field对象的创建,下面回顾下,同时介绍下Filed类的常用方法. 测试类如下: pub ...

最新文章

  1. tensorflow官方posenet模型解析
  2. Windows系统启动自动运行cmd命令
  3. 上位机获取单片机发来的数据并进行检验
  4. keepalived vrrp script|interface weight when positive,nagtive,zero vrrp's status transition
  5. android学习—— context 和 getApplicationContext()
  6. 如何在网上隐藏自己的IP地址
  7. 学成在线-处理常见视频格式avi,mp4,mov,rmvb,flv
  8. 2018-DeepLabV3+论文解读
  9. 康师傅承认:所谓矿物质水实为自来水净化而成
  10. 2016 360校招笔试编程题
  11. 个性化Ubuntu壁纸如何添加
  12. Windows10环境下Ruby安装和配置
  13. 微分的定义和介绍习题
  14. 走进VOT--《High Performance Visual Tracking with Siamese Region Proposal Network》阅读翻译
  15. YBT 6 数学基础
  16. 游戏解说是咋制作的?怎么给视频添加有趣的剧情配音?
  17. mysql pxc集群介绍_PXC集群的概述及搭建
  18. ES系列四、ES6.3常用api之文档类api
  19. vuecli2升级至vuecli3
  20. CANoe学习入门到精通

热门文章

  1. CPen虚线无效问题
  2. 使用keras时候,pycharm控制台太多日志,导致最开始的有用信息被覆盖,解决方案
  3. 找游戏关键CALL入门
  4. 西瓜无水印视频批量下载,一个脚本就够了,手把手教你批量下载西瓜无水印高清视频。
  5. 计算机cpu对什么访问最快,CPU直接访问的存储器是什么?
  6. (升级版)基本粒子结构以及宇宙现象的徦说
  7. 购买服务器的个人经验
  8. @GetMapping注解的理解
  9. SAP License:SAP软件作用是什么
  10. 锂电池电量百分比计算_锂电池充放电理论及电量计算方法详解