Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。当然反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。
一、Java反射机制主要提供下面几种用途:
1在运行时判断任意一个对象所属的类
2在运行时判断任意一个类所具有的成员变量和方法
3在运行时调用任意一个对象的方法。
二、使用java的反射机制,一般需要遵循三步:
1获得你想操作类的Class对象
2通过第一步获得的Class对象去取得操作类的方法或是属性名
3操作第二步取得的方法或是属性
三、 Java运行的时候,某个类无论生成多少个对象,他们都会对应同一个Class对象,它表示正在运行程序中的类和接口。如何取得操作类的Class对象,常用的有三种方式:
1调用Class的静态方法forName
2使用类的.class语法,如:Class<?> cls = String.class;
3调用对象的getClass方法,如:String str = "abc";Class<?> cls = str .getClass();
前面说过,Java程序的每个类都会有个Class对象与之对应。Java反射的第一步就是获得这个Class对象。当然,每个类的方法也必有一个Method对象与之对应。要通过反射的方式调用这个方法,就要首先获得这个方法的Method对象,然后用Method对象反过来调用这个方法。
通过反射给某个类的属性赋值:
1 package com.wanggc.reflection;
2
3 import java.lang.reflect.Field;
4
5 /**
6 * Java 反射之属性练习。
7 *
8 * @author Wanggc
9 */
10 public class ReflectionTest {
11 public static void main(String[] args) throws Exception {
12 // 建立学生对象
13 Student student = new Student();
14 // 为学生对象赋值
15 student.setStuName("Wanggc");
16 student.setStuAge(24);
17 // 建立拷贝目标对象
18 Student destStudent = new Student();
19 // 拷贝学生对象
20 copyBean(student, destStudent);
21 // 输出拷贝结果
22 System.out.println(destStudent.getStuName() + ":"
23 + destStudent.getStuAge());
24 }
25
26 /**
27 * 拷贝学生对象信息。
28 *
29 * @param from
30 * 拷贝源对象
31 * @param dest
32 * 拷贝目标对象
33 * @throws Exception
34 * 例外
35 */
36 private static void copyBean(Object from, Object dest) throws Exception {
37 // 取得拷贝源对象的Class对象
38 Class<?> fromClass = from.getClass();
39 // 取得拷贝源对象的属性列表
40 Field[] fromFields = fromClass.getDeclaredFields();
41 // 取得拷贝目标对象的Class对象
42 Class<?> destClass = dest.getClass();
43 Field destField = null;
44 for (Field fromField : fromFields) {
45 // 取得拷贝源对象的属性名字
46 String name = fromField.getName();
47 // 取得拷贝目标对象的相同名称的属性
48 destField = destClass.getDeclaredField(name);
49 // 设置属性的可访问性
50 fromField.setAccessible(true);
51 destField.setAccessible(true);
52 // 将拷贝源对象的属性的值赋给拷贝目标对象相应的属性
53 destField.set(dest, fromField.get(from));
54 }
55 }
56 }
57
58 /**
59 * 学生类。
60 */
61 class Student {
62 /** 姓名 */
63 private String stuName;
64 /** 年龄 */
65 private int stuAge;
66
67 /**
68 * 获取学生姓名。
69 *
70 * @return 学生姓名
71 */
72 public String getStuName() {
73 return stuName;
74 }
75
76 /**
77 * 设置学生姓名
78 *
79 * @param stuName
80 * 学生姓名
81 */
82 public void setStuName(String stuName) {
83 this.stuName = stuName;
84 }
85
86 /**
87 * 获取学生年龄
88 *
89 * @return 学生年龄
90 */
91 public int getStuAge() {
92 return stuAge;
93 }
94
95 /**
96 * 设置学生年龄
97 *
98 * @param stuAge
99 * 学生年龄
100 */
101 public void setStuAge(int stuAge) {
102 this.stuAge = stuAge;
103 }
104 }