1、首先看看需要被反射的Reflect2类的源代码
View Code
1 package reflect.chester;
2
3 public class Reflect2{
4
5 private String x="Private Field";
6 public int y=23;
7 public int z;
8 private int w;
9 /**
10 *
11 *@Title
12 *@Describe 私有 无参数 构函数函数
13 *@param
14 *@author chester
15 *@Date 2011-11-27
16 */
17 @SuppressWarnings("unused")
18 private Reflect2(){
19 this.x="无参数构造函数改变了X的值";
20 }
21 /**
22 *
23 *@Title
24 *@Describe TODO
25 *@param@param x
26 *@author chester
27 *@Date 2011-11-27
28 */
29 public Reflect2(String x){
30 this.x=x;
31 }
32
33 /**
34 *
35 *@Title print
36 *@Describe 私有成员方法
37 *@param
38 *@return void
39 *@throws
40 *@Author chester
41 *@Date 2011-11-27
42 */
43 @SuppressWarnings("unused")
44 private void print(){
45 System.out.println("Reflect2私有方法print is invoked");
46 }
47
48 @SuppressWarnings("unused")
49 private void add(){
50
51 System.out.println("Reflect2私有方法add is invoked");
52 }
53
54 }
2、再看看对Reflect进行反射的代码
View Code
1 package reflect.chester;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5 import java.lang.reflect.Method;
6
7 /**
8 *
9 * @ClassName Reflect.java
10 * @describe 反射,利用反射得到字节码,然后利用字节码得到构造函数,Field,Method,利用构造函数创建对象
11 * @author Chester
12 * @date 2011-11-26
13 * @version V1.0
14 */
15 public class Reflect {
16
17 private int x;
18 int y;
19
20 /**
21 *
22 * @Title main
23 * @Describe TODO
24 * @param@param args
25 * @return void
26 * @throws TODO
27 * @Author chester
28 * @Date 2011-11-24
29 */
30 public static void main(String[] args) {
31 // TODO Auto-generated method stub
32 /*
33 * int x = 0; x=2; System.out.println(x); String str1="shi";
34 * System.out.println(String.class==str1.getClass());//true
35 * System.out.println(str1.getClass());//java.lang.String
36 * System.out.println(Reflect.class);//reflect.chester.Reflect
37 */
38
39
40 /*
41 * 声明类的字节码对象
42 */
43 Class<?> reflect2Class;
44 /*
45 * 声明构造函数对象
46 */
47 Constructor<?>[] constructors2;
48 /*
49 * 声明Field对象;
50 */
51 Field xField,yField;
52 Field []fieldsField;
53 /*
54 * 声明Method对象
55 */
56 Method []methods;
57 Method method;
58
59
60 Reflect2 reflect2 = null;
61
62
63 try {
64
65 /**
66 * 获取类的Class对象的3种方法
67 * Reflect.class
68 * getClass
69 * static method Class.forName()
70 */
71
72 reflect2Class = Class.forName("reflect.chester.Reflect2");
73
74 /*
75 * 得到构造函数对象
76 */
77
78 constructors2 = reflect2Class.getDeclaredConstructors();
79
80 for (int i = 0; i < constructors2.length; i++) {
81 System.out.println(constructors2[i].getName());//有多少个构造函数就输出多少个reflect.chester.Reflect字符串
82 }
83
84 /*
85 * 利用反射得到的构造函数对象new一个Reflect对象 newInstance()的参数必须Object类型数组
86 * 注意参数的匹配
87 *
88 */
89
90 /*
91 * 把私有的构造函数设为可访问
92 */
93 constructors2[0].setAccessible(true);
94 reflect2 = Reflect2.class.cast(constructors2[0].newInstance(new Object[] {}));
95
96 } catch (Exception e) {
97 // TODO: handle exception
98 e.printStackTrace();
99 }
100
101 /*
102 * xField设置为可访问,不然会抛出异常
103 */
104
105 try {
106
107 /*
108 * 实例化Field,fieldsField对象
109 * public Field getField(String name)返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定 “公共" 成员字段
110 * public Field[] getFields()返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段
111 * public Field getDeclaredField(String name)返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段
112 * public Field[] getDeclaredFields()返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段
113 */
114 xField = Reflect2.class.getDeclaredField("x");
115 //yField=Reflect2.class.getDeclaredField("y");
116 yField=Reflect2.class.getField("y");
117 fieldsField=Reflect2.class.getDeclaredFields();
118
119 /*
120 * 循环输出Reflect2类的Field的名字
121
122 for (int i = 0; i < fieldsField.length; i++) {
123 System.out.println(fieldsField[i].getName());
124 }
125 */
126 for(Field field:fieldsField){
127 System.out.println(field);
128 }
129 /*
130 * 把私有变量X设置为可访问
131 */
132 xField.setAccessible(true);
133 // 这个非常重要reflect2,不然不知道作用于那个对象
134 System.out.println("访问到reflect2对象的私有变量 x:" + xField.get(reflect2));
135 // System.out.println(xField.getDeclaringClass());//class reflect.chester.Reflect2
136 System.out.println("直接访问reflect2对象的y域:"+reflect2.y);
137 System.out.println("通过yField.get(reflect2)访问y域:"+yField.get(reflect2));
138
139 /*
140 * 利用发射改变了X的值
141 */
142 xField.set(reflect2,"利用发射改变了X的值");
143 System.out.println("XField.set()后的值 x:" + xField.get(reflect2));
144
145 /*
146 * 实例化methods对象
147 * public Method getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,
148 * 它反映此 Class 对象所表示的类或接口的指定" 公共成员 "方法
149 *
150 * public Method[] getMethods()返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口
151 * (包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法
152 *
153 * public Method getDeclaredMethod(String name,Class<?>... parameterTypes)
154 * 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法
155 *
156 * public Method[] getDeclaredMethods()返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
157 * 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
158 */
159 methods=Reflect2.class.getDeclaredMethods();
160 /*
161 * getDeclaredMethod()第2个参数是你要print方法参数的class,int.class,String.class,long.class或者是自定义的class
162 * 当参数为空时使用new Class[]{ }
163 */
164 method=Reflect2.class.getDeclaredMethod("print",new Class[]{ } );
165 methods[1].setAccessible(true);
166 methods[0].setAccessible(true);
167 method.setAccessible(true);
168 /*
169 * invoke的时候,注意参数要一致
170 */
171 methods[0].invoke(reflect2, new Object[]{});
172 methods[1].invoke(reflect2, new Object[]{});
173 method.invoke(reflect2, new Object[]{});
174
175
176 } catch (SecurityException e) {
177 // TODO Auto-generated catch block
178 e.printStackTrace();
179 } catch (Exception e) {
180 // TODO Auto-generated catch block
181 e.printStackTrace();
182 }
183
184 }
185
186 /**
187 *
188 * @Title
189 * @Describe TODO
190 * @param@param x
191 * @param@param y
192 * @author chester
193 * @Date 2011-11-24
194 */
195 public Reflect(int x, int y) {// alt+shift+s 生成构造函数
196 super();
197 this.x = x;
198 this.y = y;
199 }
200
201 /*
202 * shift + alt + s 选择生成构造函数
203 */
204 /**
205 *
206 * @Title
207 * @Describe 无参数构造函数
208 * @param
209 * @author chester
210 * @Date 2011-11-26
211 */
212 private Reflect() {
213 super();
214 this.x = 100;
215 this.y = 20;
216 }
217
218 /**
219 *
220 * @Title add
221 * @Describe TODO
222 * @param@param x
223 * @param@param y
224 * @return void
225 * @throws TODO
226 * @Author chester
227 * @Date 2011-11-24
228 */
229 public static void add(int x, int y) {
230 int z = x + y;
231 System.out.println(z);
232 String str1 = "shi";
233 System.out.println(String.class == str1.getClass());// true
234 }
235
236 }
3、输出结果
reflect.chester.Reflect2
reflect.chester.Reflect2
private java.lang.String reflect.chester.Reflect2.x
public int reflect.chester.Reflect2.y
public int reflect.chester.Reflect2.z
private int reflect.chester.Reflect2.w
访问到reflect2对象的私有变量 x:无参数构造函数改变了X的值
直接访问reflect2对象的y域:23
通过yField.get(reflect2)访问y域:23
XField.set()后的值 x:利用发射改变了X的值
Reflect2私有方法add is invoked
Reflect2私有方法print is invoked
Reflect2私有方法print is invoked