利用反射解析方法

利用Java中的反射我们可以解析类中各个组成部分,下面将介绍利用反射来解析方法体:

首先,我们来先看下所解析类的源码:

Student类:

      

1 public class Student {
2
3
4
5 public static void study(){
6
7 System.out.println("好好学习、天天向上!");
8
9 }
10
11 public int getSum(int a,int b){
12
13 int sum=a+b;
14
15 return sum;
16
17 }
18
19 private void disPlay(String name,int age){
20
21 System.out.println("解析中........");
22
23 }
24
25
26
27 public static void main(String[] args) {
28
29 System.out.println("解析成功.........");
30
31 }
32
33 private String name;
34
35 private int age;
36
37 private int sex;
38
39 public String getName() {
40
41 return name;
42
43 }
44
45 public void setName(String name) {
46
47 this.name = name;
48
49 }
50
51 }

①       我们来获取以下Student类中都有哪些方法:

 

1         // 1.加载类
2  
3 Class clss = Class.forName("JUnit01.Student");
4
5 // 2.解析加载类的构造器
6  
7 Constructor csr = clss.getConstructor(null);
8
9 // 3.创建Student类对象
10  
11 Student student = (Student) csr.newInstance(null);
12
13 // 4.执行Class的getMethods方法、返回的是一个方法对象数组
14  
15 Method method[] = clss.getMethods();
16
17 // 5.遍历输出获得的方法
18  
19 for (Method m : method) {
20
21 System.out.println(m.toGenericString());
22
23 }
  

这里要注意的是:

一、  在创建该类对象的时候可以使用这种方法创建

例:

Student student = (Student)clss.newINstance()

              但在使用该方法创建类对象时必须保证解析的类中必须有一个无参构造方法

二、 在许多获得的方法名称中有一些方法并不是该类下的方法,而是该类继承于父类Object的方法

控制台输出结果为:

      既然我们知道了该类中的一些方法,那我们就选择其中一个方法来进行解析的测试

我们来解析Student类中的study()方法:

 

1     @Test
2
3 public void test01() throws Exception {
4
5 // 1.加载类
6  
7 Class clss = Class.forName("JUnit01.Student");
8
9 Student student = (Student) clss.newInstance();
10
11 // 2.解析方法
12  
13 Method method = clss.getMethod("study", null);
14
15 // 3.执行该方法
16  
17 method.invoke(student, null);
18
19 }

Class对象获取方法的方法getMethod()需要的两个参数分别是方法的名字和需要的参数类型的类,而执行方法的方法invoke()需要的两个参数分别是类对象和方法所需要的值。

最终输出结果为:

好好学习、天天向上!

可见该方法体已经执行;

③       上面我们解析了无参的方法study,那么我们下面来解析一个有参的方法,方法体源码可以在开始的Student的类中找到,具体解析源码如下:

 

1     @Test
2
3 public void test02() throws Exception {
4
5 // 1.加载类
6  
7 Class clss = Class.forName("JUnit01.Student");
8
9 Student student = (Student) clss.newInstance();
10
11 // 2.解析方法
12  
13 Method method = clss.getMethod("getSum", int.class, int.class);
14
15 // 3.执行方法
16
17 Object obj = method.invoke(student, 13, 11);
18
19
20
21 System.out.println((Integer) obj);
22
23 }

       这里要注意invoke()方法的返回值为Object对象,在上面解析无参方法study时也会返回这一对象,但study返回值为空,所以输出也为空;

④       以上解析的都是公有的方法,那么如何解析类中的私有方法呢?我们应该用到了设置类访问权限的问题,具体源码如下:

 

1     @Test
2
3 public void test03() throws Exception {
4
5 // 1.加载类
6
7 Class clss = Class.forName("JUnit01.Student");
8
9 // 2.创建类的实例
10
11 Student student = (Student) clss.newInstance();
12
13 // 3.解析方法(私有方法需要用getDeclaredMethod方法)
14
15 Method method = clss.getDeclaredMethod("disPlay", String.class,
16
17 int.class);
18
19 // 4.对于类中的私有方法需要先暴力反射
20
21 method.setAccessible(true);
22
23 // 5.执行方法
24
25 Object obj = method.invoke(student, "c", 18);
26
27 }

这里值得注意的是获取类对象中的私有方法需要使用getDeclaredMethod方法,然后对私有方法进行暴力反射后执行;

⑤       最后我们对类中的main方法进行解析,源码如下:

 

1     @Test
2
3 public void test04() throws Exception {
4
5 // 1.加载类
6
7 Class clss = Class.forName("JUnit01.Student");
8
9 // 2.创建类的实例对象
10
11 Student student = (Student) clss.newInstance();
12
13 // 3.解析方法
14
15 Method method = clss.getMethod("main", String[].class);
16
17 // 4.执行方法
18
19 method.invoke(student, new Object[] { new String[] { "13" } });
20
21 }

这里值得注意的是:

在JDK 1.4中,解析main方法参数时只是解析单纯的String[] args数组;

而在JDK 1.5中,解析main方法参数时把该参数当做可变参数来解析,所以在对main方法解析时需要把传参塑形为Object对象

最终执行结果为:

解析成功.........

以上就是通过反射方法来解析类中的私有、公有的方法,希望大家共同学习,提出宝贵的建议和意见。

posted @ 2011-02-28 17:16  Laughing_Vzr@Stand By  阅读(691)  评论(0编辑  收藏  举报