反射机制的深入应用

1  通过反射调用类中的方法

---------------------------调用无参数方法

 1 public class InstanceDemo {
 2     public static void main(String[] args) {
 3         Class<?> c = null;
 4         try {
 5             c = Class.forName("com.matto.InstanceDemo.Person");
 6         } catch (Exception e) {
 7             e.printStackTrace();
 8         }
 9         try {
10             Method met = c.getMethod("say");        //指定将调用这个没有参数的方法
11             met.invoke(c.newInstance());            //调用方法,必须传递对象实例
12         } catch (Exception e) {
13             e.printStackTrace();
14         }
15         
16     }
17 }

---------------------------调用有参数方法

 1 public class InstanceDemo {
 2     public static void main(String[] args) {
 3         Class<?> c = null;
 4         try {
 5             c = Class.forName("com.matto.InstanceDemo.Person");
 6         } catch (Exception e) {
 7             e.printStackTrace();
 8         }
 9         try {
10             Method met = c.getMethod("sayChina",String.class,int.class);        //指定将调用这个有参数的方法
11             String rv = (String)met.invoke(c.newInstance(),"Matto",30);         //调用方法,必须传递对象实例,并传入两个参数
12                                                                                 //此方法的返回值是String类型,故以String接收
13             System.out.println(rv);
14         } catch (Exception e) {
15             e.printStackTrace();
16         }
17 
18     }
19 }

2  调用getter与setter方法

 1 public class InstanceDemo {
 2     public static void main(String[] args) {
 3         Class<?> c = null;
 4         Object object = null;
 5         try {
 6             c = Class.forName("com.matto.InstanceDemo.Person");
 7         } catch (Exception e) {
 8             e.printStackTrace();
 9         }
10         try {
11             object = c.newInstance();
12         } catch (Exception e) {
13             e.printStackTrace();
14         }
15         setter(object,"name","Matto",String.class);
16         setter(object,"age",28,int.class);
17         System.out.print("姓名:");
18         getter(object,"name");
19         System.out.print("年龄:");
20         getter(object,"age");
21     }
22 
23     //单词首字母大写
24     public static String initStr(String old){
25         String string = old.substring(0,1).toUpperCase() + old.substring(1);
26         return string;
27     }
28 
29     /**
30      * 
31      * @param object    操作的对象
32      * @param att       操作的属性
33      * @param value     设置的值
34      * @param type      参数类型,就是要设置的值的类型
35      */
36     //调用setter方法
37     public static void setter(Object object,String att,String value,Class<?> type){
38         Method met = null;
39         try {
40             met = object.getClass().getMethod("set" + initStr(att),type);
41             met.invoke(object,value);
42         } catch (Exception e) {
43             e.printStackTrace();
44         }
45     }
46 
47     //调用getter方法
48     public static void getter(Object object,String att){
49         try {
50             Method met = object.getClass().getMethod("get" + initStr(att));
51             System.out.println(met.invoke(object,att));                     //接收方法的返回值
52         } catch (Exception e) {
53             e.printStackTrace();
54         }
55     }
56 }

3  通过反射操作属性---此方法不推荐,原因是此方法以扩大类属性的访问权限后直接操作属性。     最好使用上述的 getter和setter方法

 1 public class InstanceDemo {
 2     public static void main(String[] args) {
 3         Class<?> c = null;
 4         Object object = null;
 5         try {
 6             c = Class.forName("com.matto.InstanceDemo.Person");
 7             object = c.newInstance();
 8             //获取属性
 9             Field nameField = c.getDeclaredField("name");
10             Field ageField = c.getDeclaredField("age");
11             //设置可外部访问,并设置值
12             nameField.setAccessible(true);
13             nameField.set(object,"Matto");
14             ageField.setAccessible(true);
15             ageField.set(object,28);
16             //通过get取得属性内容
17             System.out.println("name : " + nameField.get(object));
18             System.out.println("age : " +ageField.get(object));
19             
20         } catch (Exception e) {
21             e.printStackTrace();
22         }
23     }
24 }

4  通过反射操作数组:反射机制不仅只能用于类上,还可以应用在任意的引用数据类型的数据上。

------------------得到数组信息并修改数组内容

 1 public class InstanceDemo {
 2     public static void main(String[] args) {
 3         int temp[] = {1,2,3};
 4         Class<?> c = temp.getClass().getComponentType();    //取得数组的Class实例
 5         System.out.println(c.getName());                    //输出数组的名称
 6         System.out.println(Array.getLength(temp));          //取得数组的长度
 7         System.out.println(Array.get(temp,0));              //取得数组的第一个内容
 8         
 9         Array.set(temp,0,6);                                //修改数组第一个内容为6
10     }
11 }