04. Java如何通过反射获取成员方法

a large storm in the ocean

这一节主要使用反射中的Method类来获取成员方法。通过以下中的任何方式都会获取Method类:

  • getMethods()
  • getMethods(String name,Class<?> …parameterTypes)
  • getDeclaredMethods()
  • getDeclaredMethods(String name,Class<?>…parameterTypes)

Method类的常用方法:

静态方法名称 说明
getName() 获取该方法的名称
getParameterType() 按照声明顺序以 Class 数组的形式返回该方法各个参数的类型
getReturnType() 以 Class 对象的形式获得该方法的返回值类型
getExceptionTypes() 以 Class 数组的形式获得该方法可能抛出的异常类型
invoke(Object obj,Object…args) 利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型
isVarArgs() 查看该方法是否允许带有可变数量的参数,如果允许返回 true,否则返回 false
getModifiers() 获得可以解析出该方法所采用修饰符的整数

实例

如何使用Method类的方法获取动态类中的方法信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.example.basejava.reflect;

/**
* @Author yamon
* @Date 2023-07-13 15:39
* @Description
* @Version 1.0
*/
public class Book1 {
// static 作用域方法
static void staticMethod() {
System.out.println("执行staticMethod()方法");
}

// public 作用域方法
public int publicMethod(int i) {
System.out.println("执行publicMethod()方法");
return 100 + i;
}

// protected 作用域方法
protected int protectedMethod(String s, int i) throws NumberFormatException {
System.out.println("执行protectedMethod()方法");
return Integer.valueOf(s) + i;
}

// private 作用域方法
private String privateMethod(String... strings) {
System.out.println("执行privateMethod()方法");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < sb.length(); i++) {
sb.append(strings[i]);
}
return sb.toString();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.example.basejava.reflect;

import java.lang.reflect.Method;

/**
* @Author yamon
* @Date 2023-07-13 15:40
* @Description
* @Version 1.0
*/
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
Book1 book = new Book1();
Class<?> aClass = Class.forName("com.example.basejava.reflect.Book1");
// 获取book1类中的所有方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("方法名称为:" + declaredMethod.getName());
System.out.println("方法是否带有可变数量的参数:" + declaredMethod.isVarArgs());
System.out.println("方法的参数类型依次为:");
// 获取所有参数类型
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println(" " + parameterType);
}
// 获取返回值类型
System.out.println("方法的返回值类型为:" + declaredMethod.getReturnType());
System.out.println("方法可能抛出的异常类型有:");
Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
System.out.println(" " + exceptionType);
}
boolean isTurn = true;
while (isTurn) {
try { // 如果该成员变量的访问权限为private,则抛出异常
isTurn = false;
if ("staticMethod".equals(declaredMethod.getName())) {
// 调用没有参数的方法
declaredMethod.invoke(book);
} else if ("publicMethod".equals(declaredMethod.getName())) {
// 调用一个参数的方法
System.out.println("publicMethod(10)的返回值为:" + declaredMethod.invoke(book, 10));
} else if ("protectedMethod".equals(declaredMethod.getName())) {
// 调用两个参数的方法
System.out.println("protectedMethod(10,15)的返回值为:" + declaredMethod.invoke(book, "10", 15));
} else if ("privateMethod".equals(declaredMethod.getName())) {
// 调用可变数量参数的方法
Object[] parameters = new Object[]{new String[]{"J", "A", "V", "A"}};
System.out.println("privateMethod()的返回值为:" + declaredMethod.invoke(book, parameters));
}
} catch (Exception e) {
System.out.println("在设置成员变量值时抛出异常,下面执行setAccessible()方法");
// 设置为允许访问private方法
declaredMethod.setAccessible(true);
isTurn = true;
}
}
System.out.println("=============================\n");
}
}
}

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
方法名称为:protectedMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
class java.lang.String
int
方法的返回值类型为:int
方法可能抛出的异常类型有:
class java.lang.NumberFormatException
执行protectedMethod()方法
protectedMethod("10",15)的返回值为:25
=============================

方法名称为:publicMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
int
方法的返回值类型为:int
方法可能抛出的异常类型有:
执行publicMethod()方法
publicMethod(10)的返回值为:110
=============================

方法名称为:staticMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
方法的返回值类型为:void
方法可能抛出的异常类型有:
执行staticMethod()方法
=============================

方法名称为:privateMethod
方法是否带有可变数量的参数:true
方法的参数类型依次为:
class [Ljava.lang.String;
方法的返回值类型为:class java.lang.String
方法可能抛出的异常类型有:
在设置成员变量值时抛出异常,下面执行setAccessible()方法
执行privateMethod()方法
privateMethod()的返回值为:
=============================


Process finished with exit code 0