`

黑马程序员----反射

 
阅读更多
反射

---------------------- android培训java培训、期待与您交流! ----------------------


一.Class类
java类用于描述一类是事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则是由这个类的实例对象确定的,不同的实例对象有不同的属性值。

1.得到各个字节码对应的实例对象
类名.class:Date.class
对象.getClass():new Date().getClass()
Class.forName("全类名"):Class.forName("java.util.Date");
----代码-----------------------------------------
Java代码   
1.	import java.util.*; 
2.	class ClassDemo 
3.	{ 
4.	public static void main(String[] args) 
5.	{ 
6.	try 
7.	{ 
8.	Date d = new Date(); 
9.	System.out.println(Date.class); 
10.	System.out.println(d.getClass()); 
11.	System.out.println(Class.forName("java.util.Date")); 
12.	} 
13.	catch (ClassNotFoundException cnfe) 
14.	{ 
15.	cnfe.printStackTrace(); 
16.	} 
17.	} 
18.	} 
19.	
20.	/*运行结果: 
21.	class java.util.Date 
22.	class java.util.Date 
23.	class java.util.Date 
24.	*/ 
----代码结束-------------------------------------

2.九个预定义的Class对象
八个基本数据类型 byte,char,short,int,long,float,double,boolean
加一个 void
----代码-----------------------------------------
Java代码   
1.	class ReflectTest 
2.	{ 
3.	public static void main(String[] args) 
4.	{ 
5.	String s = "abc"; 
6.	Class cls1 = s.getClass(); 
7.	System.out.println("cls1对应的对象是基本数据类型吗? " + cls1.isPrimitive()); 
8.	System.out.println("int是基本书记类型吗? " + int.class.isPrimitive()); 
9.	System.out.println("int对应的字节码与Integer对应的字节码相等吗? " + (int.class == Integer.class)); 
10.	System.out.println("int 与 Integer 类型相等吗? " + (int.class == Integer.TYPE)); 
11.	System.out.println("int数组是基本数据类型吗?" + int[].class.isPrimitive()); 
12.	System.out.println("判断实例对象是否为数组使用方法为isArray() int[].class.isArray(): " + int[].class.isArray()); 
13.	} 
14.	} 
15.	
16.	/*结果: 
17.	
18.	cls1对应的对象是基本数据类型吗? false 
19.	int是基本书记类型吗? true 
20.	int对应的字节码与Integer对应的字节码相等吗? false 
21.	int 与 Integer 类型相等吗? true 
22.	int数组是基本数据类型吗?false 
23.	判断实例对象是否为数组使用方法为isArray() int[].class.isArray(): true 
24.	
25.	*/ 
----代码结束-------------------------------------

二.反射
反射就是把Java类中的各个成分映射成相应的java类

1.Constructor类
代表某个类中的一个构造方法
先获得Constructor对象
Class.getConstructors(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
得到了Constructor对象再调用newInstance(Object... initargs)方法创建实例对象
----代码-----------------------------------------
Java代码   
1.	import java.lang.reflect.*; 
2.	class ConstructorDemo 
3.	{ 
4.	public static void main(String[] args) 
5.	{ 
6.	try 
7.	{ 
8.	Constructor con = String.class.getConstructor(StringBuffer.class);//获得方法时用到的类型 
9.	String s = (String)con.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象 
10.	System.out.println(s.charAt(2)); 
11.	} 
12.	catch (Exception e) 
13.	{ 
14.	e.printStackTrace(); 
15.	} 
16.	} 
17.	} 
18.	/*结果 
19.	e 
20.	*/ 
----代码结束-------------------------------------

2.Field类
代表某个类中的一个成员变量

----代码开始-------------------------------------
Java代码   
1.	import java.lang.reflect.*; 
2.	class RefiecPointDemo 
3.	{ 
4.	private int x; 
5.	public int y; 
6.	private int z; 
7.	private String s1; 
8.	private String s2; 
9.	private String s3; 
10.	public String s4; 
11.	public RefiecPointDemo(int x,int y,int z) 
12.	{ 
13.	this.x = x; 
14.	this.y = y; 
15.	this.z = z; 
16.	} 
17.	public RefiecPointDemo(int x,int y,int z,String s1,String s2,String s3,String s4) 
18.	{ 
19.	this.x = x; 
20.	this.y = y; 
21.	this.z = z; 
22.	this.s1 = s1; 
23.	this.s2 = s2; 
24.	this.s3 = s3; 
25.	this.s4 = s4; 
26.	} 
27.	} 
28.	class RefiecPoint 
29.	{ 
30.	public static void main(String[] args) 
31.	{ 
32.	try 
33.	{ 
34.	System.out.println("第一部分:"); 
35.	RefiecPointDemo rd = new RefiecPointDemo(2,7,13); 
36.	//要获得类中的成员变量,首先要获得该对象的字节码 
37.	Class c = rd.getClass(); 
38.	//获得字节码后获得y变量的对象 
39.	Field fY = c.getField("y"); 
40.	//得到对象后,获取值,还要指定是从那个对象中获取的 
41.	System.out.println(fY.get(rd)); 
42.	//以上只能获取访问修饰符为public的变量 
43.	//下面是获取所有访问修饰符的变量 
44.	/* 
45.	获得字节码就要用到getDeclaredField()表示 
46.	的类或接口的以声明的字段 
47.	*/ 
48.	Field fX = c.getDeclaredField("x"); 
49.	//获得字节码后并不能直接使用,必须暴力获得访问权限 
50.	//用到的方法时Field父类AccessibleObject类中 
51.	//setAccessible(boolean flag)方法 
52.	fX.setAccessible(true); 
53.	//现在此对象才有访问权限 
54.	System.out.println(fX.get(rd)); 
55.	//----------------------------- 
56.	for (int i=0 ;i<2 ;i++ ) 
57.	System.out.println(); 
58.	System.out.println("第二部分"); 
59.	/* 
60.	发现API中有Field[] getDeclaredFields()和Filed[] getFields[] 
61.	
62.	 
63.	try一try 
64.	*/ 
65.	//不知道有什么变量那肯定就不知道访问权限了,所以首选暴力的 
66.	Field[] fAll = c.getDeclaredFields(); 
67.	for(Field f : fAll) 
68.	{ 
69.	f.setAccessible(true); 
70.	System.out.println(f.getName() + "的值: " + f.get(rd)); 
71.	} 
72.	//OK 完全得到结果。 
73.	//---------------------- 
74.	for (int i=0 ;i<2 ;i++ ) 
75.	System.out.println(); 
76.	System.out.println("第三部分:"); 
77.	//把所有String类型的变量值“b”改为“a” 
78.	//创建需反射类对象 
79.	RefiecPointDemo rd1 = new RefiecPointDemo(3,5,7,"nbnbbaade","bfasbbe","fgrbdffbfbsdb","sdfesfe"); 
80.	//获得此对象字节码 
81.	Class c1 = rd1.getClass(); 
82.	//获取声明的所有变量 
83.	Field[] fAll1 = c1.getDeclaredFields(); 
84.	System.out.println("原始值:"); 
85.	//循环操作 
86.	for(Field f : fAll1) 
87.	{ 
88.	//修改权限 
89.	f.setAccessible(true); 
90.	//获得所有Sting类型 
91.	if(f.getType().getSimpleName().equals("String")) 
92.	{ 
93.	String temp = f.get(rd1).toString(); 
94.	System.out.println(f.getName() + "的值为:" + temp); 
95.	StringBuilder sb = new StringBuilder(); 
96.	for (int i=0;i < temp.length() ;i++ ) 
97.	{ 
98.	if(temp.charAt(i) == 'b') 
99.	{ 
100.	sb.append('a'); 
101.	continue; 
102.	} 
103.	sb.append(temp.charAt(i)); 
104.	} 
105.	f.set(rd1,sb.toString()); 
106.	//System.out.println(sb); 
107.	} 
108.	} 
109.	//修改后的值 
110.	System.out.println("修改后的值:"); 
111.	fAll1 = c1.getDeclaredFields(); 
112.	for(Field f : fAll1) 
113.	{ 
114.	f.setAccessible(true); 
115.	System.out.println(f.getName() + "的值: " + f.get(rd1)); 
116.	} 
117.	//------------------------------------------- 
118.	for (int i=0 ;i<2 ;i++ ) 
119.	System.out.println(); 
120.	System.out.println("第四部分:"); 
121.	 
122.	 
123.	RefiecPointDemo rd2 = new RefiecPointDemo(3,5,7,"nbnbbaade","bfasbbe","fgrbdffbfbsdb","sdfesfe"); 
124.	//获得此对象字节码 
125.	Class c2 = rd2.getClass(); 
126.	//获取声明的所有变量 
127.	Field[] fAll2 = c2.getDeclaredFields(); 
128.	System.out.println("原始值:"); 
129.	//循环操作 
130.	for(Field f : fAll2) 
131.	{ 
132.	//if(f.getType().getSimpleName().equals("String"))为什么非要转换成字符串呢?字节码也可以比较呀 
133.	//想到了要先获得类型看看是不是String,那么getType()返回的的是Class我们可以找到String.class去比较呀 
134.	if(f.getType() == String.class)//这里用==比用equals更加专业,返回的结果相同 
135.	{ 
136.	/*用了这么多代码就是将字符串里某个字符换为另外一个字符,但Sting的API有现成的方法。悲哀 
137.	String temp = f.get(rd1).toString(); 
138.	System.out.println(temp); 
139.	StringBuilder sb = new StringBuilder(); 
140.	for (int i=0;i < temp.length() ;i++ ) 
141.	{ 
142.	if(temp.charAt(i) == 'b') 
143.	{ 
144.	sb.append('a'); 
145.	continue; 
146.	} 
147.	sb.append(temp.charAt(i)); 
148.	}*/ 
149.	//修改权限 
150.	f.setAccessible(true); 
151.	String oldString = f.get(rd2).toString(); 
152.	System.out.println(f.getName() + "的值为:" + oldString); 
153.	String newString = oldString.replace('a','b'); 
154.	f.set(rd2,newString); 
155.	} 
156.	} 
157.	//修改后的值 
158.	System.out.println("修改后的值:"); 
159.	fAll2 = c1.getDeclaredFields(); 
160.	for(Field f : fAll2) 
161.	{ 
162.	f.setAccessible(true); 
163.	System.out.println(f.getName() + "的值: " + f.get(rd1)); 
164.	} 
165.	} 
166.	catch (Exception e) 
167.	{ 
168.	e.printStackTrace(); 
169.	} 
170.	} 
171.	} 
172.	
173.	/*结果: 
174.	第一部分: 
175.	7 
176.	2 
177.	
178.	
179.	第二部分 
180.	x的值: 2 
181.	y的值: 7 
182.	z的值: 13 
183.	s1的值: null 
184.	s2的值: null 
185.	s3的值: null 
186.	s4的值: null 
187.	
188.	
189.	第三部分: 
190.	原始值: 
191.	s1的值为:nbnbbaade 
192.	s2的值为:bfasbbe 
193.	s3的值为:fgrbdffbfbsdb 
194.	s4的值为:sdfesfe 
195.	修改后的值: 
196.	x的值: 3 
197.	y的值: 5 
198.	z的值: 7 
199.	s1的值: nanaaaade 
200.	s2的值: afasaae 
201.	s3的值: fgradffafasda 
202.	s4的值: sdfesfe 
203.	
204.	
205.	第四部分: 
206.	原始值: 
207.	s1的值为:nbnbbaade 
208.	s2的值为:bfasbbe 
209.	s3的值为:fgrbdffbfbsdb 
210.	s4的值为:sdfesfe 
211.	修改后的值: 
212.	x的值: 3 
213.	y的值: 5 
214.	z的值: 7 
215.	s1的值: nanaaaade 
216.	s2的值: afasaae 
217.	s3的值: fgradffafasda 
218.	s4的值: sdfesfe 
219.	*/ 

----代码结束-------------------------------------

3. Method 类
代表某个类中的一个成员方法
----代码开始-------------------------------------
Java代码   
1.	import java.lang.reflect.*; 
2.	class MethodDemo 
3.	{ 
4.	public static void main(String[] args) 
5.	{ 
6.	MethodTest mt = new MethodTest(); 
7.	Method[] method = mt.getClass().getMethods(); 
8.	Method[] methods = mt.getClass().getDeclaredMethods(); 
9.	System.out.println("共有方法 " + method.length + " 个"); 
10.	//mt.getClass().getMethods();这个方法返回的是本类所有public方法及父类所有可访问方法 
11.	for(Method m : method) 
12.	{ 
13.	System.out.println("getName(): " + m.getName()); 
14.	} 
15.	System.out.println(); 
16.	//mt.getClass().getDeclaredMethods(); 访问的是本类中所有方法 
17.	
18.	/*结果 分开写了!上面for打出来的的结果 
19.	
20.	共有方法 11 个 
21.	getName(): show1 //反射的类的public方法 
22.	getName(): show2 //反射的类的public方法 
23.	getName(): wait //父类Object可以访问的方法 
24.	getName(): wait //父类Object可以访问的方法 
25.	getName(): wait //父类Object可以访问的方法 
26.	getName(): equals //父类Object可以访问的方法 
27.	getName(): toString //父类Object可以访问的方法 
28.	getName(): hashCode //父类Object可以访问的方法 
29.	getName(): getClass //父类Object可以访问的方法 
30.	getName(): notify //父类Object可以访问的方法 
31.	getName(): notifyAll //父类Object可以访问的方法 
32.	
33.	*/ 
34.	System.out.println("共有方法 " + methods.length + " 个"); 
35.	for(Method m : methods) 
36.	{ 
37.	
38.	//m.setAccessible(true); 
39.	System.out.println("getName(): " + m.getName());//以 String 形式返回此 Method 对象表示的方法名称。无需设置权限或说暴力破解也可获得私有方法 
40.	System.out.println("getGenericReturnType() : " + m.getGenericReturnType());//返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。 
41.	System.out.println("getModifiers(): " + m.getModifiers());//以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符 
42.	System.out.println("getParameterTypes(): " + m.getParameterTypes().length);//按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。 
43.	System.out.println("getReturnType(): " + m.getReturnType());//返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。 
44.	System.out.println("isSynthetic() : " + m.isSynthetic());//如果此方法为复合方法,则返回 true;否则,返回 false。\ 
45.	System.out.println("isVarArgs(): " + m.isVarArgs());//如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。 
46.	System.out.println("toGenericString(): " + m.toGenericString());//返回描述此 Method 的字符串,包括类型参数。 
47.	System.out.println(); 
48.	System.out.println("-----华丽的分割线登场-------"); 
49.	System.out.println(); 
50.	
51.	/*结果: 
52.	共有方法 5 个 
53.	getName(): show1 
54.	getGenericReturnType() : void 
55.	getModifiers(): 9 
56.	getParameterTypes(): 0 
57.	getReturnType(): void 
58.	isSynthetic() : false 
59.	isVarArgs(): false 
60.	toGenericString(): public static void MethodTest.show1() 
61.	
62.	--------------- 
63.	
64.	getName(): show2 
65.	getGenericReturnType() : int 
66.	getModifiers(): 1 
67.	getParameterTypes(): 0 
68.	getReturnType(): int 
69.	isSynthetic() : false 
70.	isVarArgs(): false 
71.	toGenericString(): public int MethodTest.show2() 
72.	
73.	--------------- 
74.	
75.	getName(): show3 
76.	getGenericReturnType() : class java.lang.String 
77.	getModifiers(): 8 
78.	getParameterTypes(): 0 
79.	getReturnType(): class java.lang.String 
80.	isSynthetic() : false 
81.	isVarArgs(): false 
82.	toGenericString(): static java.lang.String MethodTest.show3() 
83.	
84.	---------------- 
85.	
86.	getName(): show4 
87.	getGenericReturnType() : void 
88.	getModifiers(): 10 
89.	getParameterTypes(): 0 
90.	getReturnType(): void 
91.	isSynthetic() : false 
92.	isVarArgs(): false 
93.	toGenericString(): private static void MethodTest.show4() 
94.	
95.	--------------- 
96.	
97.	getName(): show5 
98.	getGenericReturnType() : class java.lang.String 
99.	getModifiers(): 128 
100.	getParameterTypes(): 2 
101.	getReturnType(): class java.lang.String 
102.	isSynthetic() : false 
103.	isVarArgs(): true 
104.	toGenericString(): java.lang.String MethodTest.show5(int,int[]) 
105.	
106.	//--------------- 
107.	
108.	*/ 
109.	} 
110.	} 
111.	} 
112.	class MethodTest 
113.	{ 
114.	public static void show1() 
115.	{ 
116.	int i = 0; 
117.	String s = "s"; 
118.	System.out.println("public static void show()"); 
119.	} 
120.	public int show2() 
121.	{ 
122.	int i = 0; 
123.	String s = "s"; 
124.	System.out.println("public void show2()"); 
125.	return i; 
126.	} 
127.	static String show3() 
128.	{ 
129.	int i = 0; 
130.	String s = "s"; 
131.	System.out.println("static void show3()"); 
132.	return s; 
133.	} 
134.	private static void show4() 
135.	{ 
136.	int i = 0; 
137.	String s = "s"; 
138.	System.out.println("private static void show4()"); 
139.	} 
140.	String show5(int a,int ... b) 
141.	{ 
142.	String s = "s"; 
143.	System.out.println("String show5()"); 
144.	return s; 
145.	} 
146.	} 

---------------------- android培训java培训、期待与您交流! ---------------------- 详细请查看:http://edu.csdn.net/heima
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics