Method类的使用
概述
每个方法都由修饰符、返回值、参数、注解和抛出的异常组成。而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类的使用相关推荐
- java学习(175):method类反射机制
//class反射编程 //定义一个学生类 public class test124 {public String name;protected int age;double height;priva ...
- method java_解析Java中的Field类和Method类
Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特 ...
- java method field_java_解析Java中的Field类和Method类,Field类
Field类中定义了一些方 - phpStudy...
解析Java中的Field类和Method类 Field类Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值.将这些方法与继承而来的member方法结合在一起.就可以使我们能够 ...
- java-反射-Method类走读
背景 之前走读了Class类的函数,能让我们更灵活的获取一个类中的信息.然而仅有类信息还是不够的,想要达到灵活调用类中函数的功能还需要借助于reflect包的Method类,本博文将走读Method类 ...
- Class -- 10 -- Method类常用方法解析
原文链接:Class – 10 – Method类常用方法解析 相关文章: Class – 01 – System类常用方法解析 Class – 02 – Arrays类常用方法解析 Class – ...
- Java Method类简介说明
转自: Java Method类简介说明 下文笔者将讲述Java中Method类的功能简介说明,如下所示: Method类是java.lang.reflect包下Method类被聚合在Class的对象 ...
- java反射中method类中的invoke方法是做什么的,他有什么作用?
就是调用类中的方法,最简单的用法是可以把方法参数化 invoke(class, method) 比如你Test类里有一系列名字相似的方法setValue1.setValue2等等 可以把方法名存进数组 ...
- Java反射Filed、Method、Constructor类_02
文章目录 1. Field类 1.2. Field类常用方法 2. Method类 2.1. Method类常用方法 3. Constructor类 3.1. Constructor类常用方法 4.J ...
- Java反射02--Filed,Method,Constructor类
Java反射02–Filed,Method,Constructor类 一Filed类常用方法 上一篇已经说过了Field对象的创建,下面回顾下,同时介绍下Filed类的常用方法. 测试类如下: pub ...
最新文章
- tensorflow官方posenet模型解析
- Windows系统启动自动运行cmd命令
- 上位机获取单片机发来的数据并进行检验
- keepalived vrrp script|interface weight when positive,nagtive,zero vrrp's status transition
- android学习—— context 和 getApplicationContext()
- 如何在网上隐藏自己的IP地址
- 学成在线-处理常见视频格式avi,mp4,mov,rmvb,flv
- 2018-DeepLabV3+论文解读
- 康师傅承认:所谓矿物质水实为自来水净化而成
- 2016 360校招笔试编程题
- 个性化Ubuntu壁纸如何添加
- Windows10环境下Ruby安装和配置
- 微分的定义和介绍习题
- 走进VOT--《High Performance Visual Tracking with Siamese Region Proposal Network》阅读翻译
- YBT 6 数学基础
- 游戏解说是咋制作的?怎么给视频添加有趣的剧情配音?
- mysql pxc集群介绍_PXC集群的概述及搭建
- ES系列四、ES6.3常用api之文档类api
- vuecli2升级至vuecli3
- CANoe学习入门到精通