疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

JavaWeb_反射学习与总结


 

 
一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。
 
编程时什么情况下才需要加载类,并解剖出累的各个组成部分呢?
 
反射是用来做框架的。
 
从配置文件中解读类的方法等。
 
Java中有一个Class类用于代表某一个类的字节码。
 
Class类既然代表某个类的字节码,它当然就要提供加载某个类自己吗的方法:forName(). forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装。
 
另外两种得到class对象的方式
 
类名.class
 
对象.getClass()
 
下面看三种类的加载方法
 
复制代码
 1 package cn.itcast.reflect;
 2 
 3 public class Demo1 {
 4 
 5     public static void main(String[] args) throws Exception {
 6         // TODO Auto-generated method stub
 7         //加载类的字节码1,常用
 8         Class clazz1 = Class.forName("cn.itcast.reflect.Person");
 9         
10         //加载类的字节码2
11         Class clazz2 = Person.class;
12         
13         //加载类的字节码3
14         Class clazz3 = new Person().getClass();
15 
16     }
17 
18 }
复制代码
Class对象提供了如下常用方法:
 
复制代码
1 public Constructor getConstructor(Class<?>... parameterTypes)
2 public Method getMethod(String name,Class<?>... parameterTypes)
3 public Field getField(String name)
4     
5 public Constructor getDeclaredConstructor(Class<?>... parameterTypes)
6 public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
7 public Field getDeclaredField(String name) 
复制代码
这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor,Method,Field对象表示。
 
思考:假设你是一个框架的设计者,出这些成员后你会干什么?
 
 
 
先看反射类的构造方法。
 
复制代码
 1 //Demo1.java
 2 package cn.itcast.reflect;
 3 import java.lang.reflect.Constructor;
 4 import org.junit.Test;
 5 public class Demo1 {
 6 
 7     public static void main(String[] args) throws Exception {
 8         // TODO Auto-generated method stub
 9         //加载类的字节码1,常用
10         Class clazz = Class.forName("cn.itcast.reflect.Person");
11         Constructor c = clazz.getConstructor(null);
12         
13         Object obj = c.newInstance(null);
14         
15         System.out.println(obj);
16         
17 
18     }
19     
20     //反射无参的构造函数
21     @Test
22     public void test1() throws Exception{
23         Class clazz = Class.forName("cn.itcast.reflect.Person");
24         Constructor c = clazz.getConstructor(null);
25         
26         Object obj = c.newInstance(null);
27         
28         System.out.println(obj);
29     }
30     
31     
32     //反射有参的构造函数
33     @Test
34     public void test2() throws Exception{
35         Class clazz = Class.forName("cn.itcast.reflect.Person");
36         Constructor c = clazz.getConstructor(String.class);
37         
38         Person p = (Person) c.newInstance("fix");
39         System.out.println(p);
40     }
41     
42     //反射私有的,有参的构造函数
43     @Test
44     public void test3() throws Exception{
45         Class clazz = Class.forName("cn.itcast.reflect.Person");
46         Constructor c = clazz.getDeclaredConstructor(int.class);
47         c.setAccessible(true);//暴力反射
48         Person p = (Person) c.newInstance(1);
49         System.out.println(p);
50     }
51 }
复制代码
下面看反射类的方法
 
复制代码
 1 package cn.itcast.reflect;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.junit.Test;
 6 
 7 public class Demo2 {
 8     //反射方法
 9     
10     //反射不带参数的方法
11     @Test
12     public void test1() throws Exception{
13         Class clazz = Class.forName("cn.itcast.reflect.Person");
14         
15         Method method = clazz.getMethod("eat", null);
16         
17         method.invoke(clazz.newInstance(), null);
18     }
19     
20     //反射带参数的方法
21     @Test
22     public void test2() throws Exception{
23         Class clazz = Class.forName("cn.itcast.reflect.Person");
24         
25         Method method = clazz.getMethod("run", String.class);
26         
27         method.invoke(clazz.newInstance(), "上海");
28     }
29     
30     //反射带多个参数的方法
31     @Test
32     public void test3() throws Exception{
33         Class clazz = Class.forName("cn.itcast.reflect.Person");
34         
35         Method method = clazz.getMethod("run", String.class,int[].class,String[].class);
36         
37         method.invoke(clazz.newInstance(), "上海",new int[]{1,2,3},new String[]{"a","b","c"});
38     }
39     
40     
41     //反射带返回值的方法
42     @Test
43     public void test4() throws Exception{
44         Class clazz = Class.forName("cn.itcast.reflect.Person");
45         
46         Method method = clazz.getMethod("test", String.class);
47         
48         String result = (String) method.invoke(clazz.newInstance(), "上海");
49         System.out.println(result);
50     }
51     
52     
53     //反射私有方法
54     @Test
55     public void test5() throws Exception{
56         Class clazz = Class.forName("cn.itcast.reflect.Person");
57         
58         Method method = clazz.getDeclaredMethod("test2", String.class);
59         method.setAccessible(true);//暴力反射
60         String result = (String) method.invoke(clazz.newInstance(), "上海");
61         System.out.println(result);
62     }
63     
64     
65     //反射静态方法
66     @Test
67     public void test6() throws Exception{
68         Class clazz = Class.forName("cn.itcast.reflect.Person");
69         
70         Method method = clazz.getMethod("test3", String.class);
71         String result = (String) method.invoke(null, "上海");
72         System.out.println(result);
73     }
74         
75     //反射main方法
76     //通过反射调用带数组的方法,要注意处理
77     @Test
78     public void test7() throws Exception{
79         Class clazz = Class.forName("cn.itcast.reflect.Person");
80         
81         Method method = clazz.getMethod("main", String[].class);
82         //method.invoke(null, (Object)new String[]{"1","2"});
83         method.invoke(null, new Object[]{new String[]{"1","2"}});
84     }
85 }
复制代码
 
 
利用Field访问属性
 
Field对象提供了如下方法,用于设置、获取对象属性的值:
 
public void set(Object obj,Object value)
 
public Object get(Object obj)
 
复制代码
 1 package cn.itcast.reflect;
 2 
 3 import java.lang.reflect.Field;
 4 
 5 import org.junit.Test;
 6 
 7 public class Demo3 {
 8 
 9     /**
10      * 反射类的字段
11      * @throws Exception 
12      */
13     //反射公有成员变量
14     @Test
15     public void test1() throws Exception{
16         
17         Person p = new Person();
18         Class clazz = Class.forName("cn.itcast.reflect.Person");
19         
20         Field f = clazz.getField("name");
21         
22         f.set(p, "flx");
23         System.out.println(p.getName());
24         
25     }
26     
27     
28     //反射公有成员变量
29     @Test
30     public void test2() throws Exception{
31         
32         Person p = new Person();
33         p.setName("xxx");
34         Class clazz = Class.forName("cn.itcast.reflect.Person");
35         Field f = clazz.getField("name");
36         String result = (String)f.get(p);
37         System.out.println(result);
38         
39     }
40     
41     //反射final成员变量
42     @Test
43     public void test3() throws Exception{
44         
45         Person p = new Person();
46         Class clazz = Class.forName("cn.itcast.reflect.Person");
47         Field f = clazz.getField("password");
48         String result = (String)f.get(p);
49         System.out.println(result);
50         
51     }
52     
53     //反射私有成员变量
54     @Test
55     public void test4() throws Exception{
56         Person p = new Person();
57         Class clazz = Class.forName("cn.itcast.reflect.Person");
58         Field f = clazz.getDeclaredField("age");
59         f.setAccessible(true);
60         f.set(p, 123);
61         int result = (Integer)f.getInt(p);
62         System.out.println(result);
63     }
64 }
复制代码
 
 
Person类如下:
 
 
 
复制代码
 1 package cn.itcast.reflect;
 2 
 3 public class Person {
 4     
 5     public String name;//字段或成员变量
 6     private int age;
 7     
 8     public final String password="123";
 9     
10     
11     public String getName() {
12         return name;
13     }
14 
15     public void setName(String name) {
16         this.name = name;
17     }
18 
19     public int getAge() {
20         return age;
21     }
22 
23     public void setAge(int age) {
24         this.age = age;
25     }
26 
27     public Person(){
28         System.out.println("person");
29     }
30     
31     public Person(String name){
32         System.out.println(name);
33     }
34     
35     private Person(int name){
36         System.out.println(name);
37     }
38     
39     public void eat(){
40         System.out.println("eat!!!");
41     }
42     
43     public void run(String address){
44         System.out.println("跑到"+address);
45     }
46     
47     public void run(String address,int num[],String ss[]){
48         System.out.println("跑到"+address+"," +num);
49     }
50     
51     public String test(String str){
52         return str+"aaaaaa";
53     }
54     
55     private String test2(String str){
56         return str+"aaaaaa";
57     }
58     
59     public static String test3(String str){
60         return str+"aaaa";
61     }
62     
63     
64     public static void main(String[] args) {
65         System.out.println(args[0]);
66     }
67 
68 }
复制代码
如上就是反射所有常用的一些方法。