javaweb学习总结四(反射技术)

一:反射的概念

反射就是加载类,然后获取类的属性、方法、构造函数等。

 

二:加载类到内存(有硬盘字节码文件到内存)

 

三种加载类的方式:

 1 @Test
 2     // 测试加载类
 3     public void test1() throws Exception {
 4         // 第一种方式
 5         Class clazz1 = Class.forName("com.hlcui.test.Person");
 6         // 第二种方式
 7         Class clazz2 = new Person().getClass();
 8         // 第三种方式
 9         Class clazz3 = Person.class;
10     }

 

三:反射类中的组成部分

1:使用getConstructor()、getMethod()、getField(),可以反射public修饰的成员,

如果需要反射private修饰的成员,需要使用下面的getDeclaredXXX()。

2:反射构造方法

Person定义的构造方法:

 1 public Person() {
 2         System.out.println("调用无参构造方法...");
 3     }
 4 
 5     public Person(String name) {
 6         System.out.println(name);
 7     }
 8 
 9     public Person(String name, int age) {
10         System.out.println(name + ":" + age);
11     }
12 
13     private Person(List<String> list) {
14         System.out.println(list);
15     }

 

反射构造方法代码:

 1 @Test
 2     // 反射无参构造方法
 3     public void test2() throws Exception {
 4         Class clazz1 = Class.forName("com.hlcui.test.Person");
 5         Constructor c = clazz1.getConstructor(null);
 6         Person p = (Person) c.newInstance(null);
 7         System.out.println(p.name);
 8     }
 9 
10     @Test
11     // 反射参数String的构造方法
12     public void test3() throws Exception {
13         Class clazz1 = Class.forName("com.hlcui.test.Person");
14         Constructor c = clazz1.getConstructor(String.class);
15         Person p = (Person) c.newInstance("Jack");
16         System.out.println(p.name);
17     }
18 
19     @Test
20     // 反射参数为String、int的构造方法
21     public void test4() throws Exception {
22         Class clazz1 = Class.forName("com.hlcui.test.Person");
23         Constructor c = clazz1.getConstructor(String.class, int.class);
24         Person p = (Person) c.newInstance("Jack", 27);
25         System.out.println(p.name);
26     }
27 
28     @Test
29     // 反射参数为List的构造方法
30     public void test5() throws Exception {
31         Class clazz1 = Class.forName("com.hlcui.test.Person");
32         Constructor c = clazz1.getDeclaredConstructor(List.class);
33         c.setAccessible(true);
34         Person p = (Person) c.newInstance(new ArrayList());
35         System.out.println(p.name);
36     }

其中反射参数为List的构造方法,因为构造方法时private修饰的,所以必须使用getDeclaredConstructor()获取构造方法,

同时需要设置强制方法setAccessible(true);

也可以直接使用反射类获取对象,代码如下:

1 @Test
2     public void test6() throws Exception {
3         Class clazz1 = Class.forName("com.hlcui.test.Person");
4         Person p = (Person) clazz1.newInstance();
5         System.out.println(p.name);
6     }

 

2:反射方法

 

反射方法代码如下:

Person类中定义的普通方法:

 1 public void abc() {
 2         System.out.println("abc...");
 3     }
 4 
 5     public String abc(String name) {
 6         return name;
 7     }
 8 
 9     public void abc(String name, int[] i) {
10         System.out.println(name + ":" + i);
11     }
12 
13     public Class[] abc(InputStream in) {
14         return new Class[] { String.class };
15     }
16 
17     public static void abc(int i) {
18         System.out.println(i);
19     }

 

反射普通方法:

 1 @Test
 2     // public void abc()
 3     public void test7() throws Exception {
 4         Person p = new Person();
 5         Class clazz1 = Class.forName("com.hlcui.test.Person");
 6         Method m = clazz1.getMethod("abc", null);
 7         m.invoke(p, null);
 8     }
 9 
10     @Test
11     // public String abc(String name)
12     public void test8() throws Exception {
13         Person p = new Person();
14         Class clazz1 = Class.forName("com.hlcui.test.Person");
15         Method m = clazz1.getMethod("abc", String.class);
16         System.out.println(m.invoke(p, "Tom"));
17     }
18 
19     @Test
20     // public void abc(String name, int[] i)
21     public void test9() throws Exception {
22         Person p = new Person();
23         Class clazz1 = Class.forName("com.hlcui.test.Person");
24         Method m = clazz1.getMethod("abc", String.class, int[].class);
25         m.invoke(p, "Jack", new int[] { 1, 2, 3 });
26     }
27 
28     @Test
29     // public Class[] abc(InputStream in)
30     public void test10() throws Exception {
31         Person p = new Person();
32         Class clazz1 = Class.forName("com.hlcui.test.Person");
33         Method m = clazz1.getMethod("abc", InputStream.class);
34         Class[] cc = (Class[]) m.invoke(p, new FileInputStream("f:/1.txt"));
35         System.out.println(cc[0]);
36     }
37 
38     @Test
39     // public static void abc(int i)
40     public void test11() throws Exception {
41         Class clazz1 = Class.forName("com.hlcui.test.Person");
42         Method m = clazz1.getMethod("abc", int.class);
43         m.invoke(null, 27);
44     }

 Person定义的main方法:

1 public static void main(String[] args) {
2         System.out.println("调用main...");
3     }

反射main方法:

1 @Test
2     // public static void main(String[] args)
3     public void test12() throws Exception {
4         Person p = new Person();
5         Class clazz1 = Class.forName("com.hlcui.test.Person");
6         Method m = clazz1.getMethod("main", String[].class);
7         // m.invoke(p, (Object)new String[]{"1","2","3"});
8         m.invoke(p, new Object[] { new String[] { "1", "2", "3" } });
9     }

这里要注意,由于jdk5兼容了jdk1.4的特性,传入字符串数组时,它会对传入参数进行拆分,

如:new String[]{"1","2","3"}将被拆分成"1"、"2"、"3",所以直接反射会报参数个数异常,

有两种处理方法:

a:在前面加上Object  b:将数组再次放到数组中

 

3:反射字段

Person类中定义字段:

1 public String name = "Tom";
2     private int age = 27;
3     private static double salary = 8000.0;

反射字段:

 1 @Test
 2     // public String name = "Tom";
 3     public void test13() throws Exception {
 4         Person p = new Person();
 5         Class clazz1 = Class.forName("com.hlcui.test.Person");
 6         Field f = clazz1.getField("name");
 7         f.set(p, "Jack");
 8         Object obj = f.get(p);
 9         Class type = f.getType();
10         if (type.equals(String.class)) {
11             String value = (String) obj;
12             System.out.println(value);
13         }
14     }
15 
16     @Test
17     // private int age = 27;
18     public void test14() throws Exception {
19         Person p = new Person();
20         Class clazz1 = Class.forName("com.hlcui.test.Person");
21         Field f = clazz1.getDeclaredField("age");
22         f.setAccessible(true);
23         int i = (Integer) f.get(p);
24         System.out.println(i);
25     }
26 
27     @Test
28     // private static double salary = 8000.0;
29     public void test15() throws Exception {
30         Person p = new Person();
31         Class clazz1 = Class.forName("com.hlcui.test.Person");
32         Field f = clazz1.getDeclaredField("salary");
33         f.setAccessible(true);
34         double d = (Double) f.get(p);
35         System.out.println(d);
36     }

反射的知识就总结到这里!

posted @ 2016-07-26 23:34  warrior1234  阅读(642)  评论(0编辑  收藏  举报