反射
反射的基礎(chǔ)是Class類
Class:
JAVA類用于描述一類事物的共性。而是什么屬性則是由類的實(shí)例對(duì)象來確定的,不同的實(shí)例對(duì)象有不同的屬性值。
Class則是用于描述JAVA類的共性的類,描述了類的名字,訪問屬性,包名,字段名稱列表,方法名稱列表等。
Class的實(shí)例對(duì)象為某個(gè)類的字節(jié)碼。
獲取字節(jié)碼的實(shí)例對(duì)象方法有三種
1. 類名.class System.class
2. 對(duì)象.getClass new Date().getClass()
3. Class.forName("類名") Class.forName("java.util.Date")
Class cls1=Date.class //Date類的字節(jié)碼 ,已經(jīng)加載到內(nèi)存
Class cls2=p1.getClass();//調(diào)用對(duì)象的getClass()得到類的字節(jié)碼
Class.forName("java.lang.String") //返回該類字節(jié)碼
反射就是把Java類中的各種成分映射成相應(yīng)的Java類,如:一個(gè)Java類中用Class類的對(duì)象來表示,一個(gè)類中組成的部分:
成員變量,方法,構(gòu)造方法,包等信息,也是用一個(gè)個(gè)Java類來表示的
Class代表一份類字節(jié)碼
Method 類的實(shí)例對(duì)象代表 類的方法
Constructor類
Constructor類代表類中的一個(gè)構(gòu)造方法
//獲取某個(gè)類的所有構(gòu)造方法
Constructor[] constructors=Class.forName("java.lang.String").getConstructors();
//獲取某個(gè)構(gòu)造方法,要用的參數(shù)類型 如:String(StringBuffer buffer)
Constructor constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);
創(chuàng)建實(shí)例對(duì)象
通常方法:String str=new String(new StringBuffer("abcd"));
//Constructor類的 newInstance() 方法
反射方法:String str=(String)constructor.newInstance(new StringBuffer("abc"))
Field類,代表某個(gè)類的屬性
Field fieldy=pt1.getClass().getField("y"); 得出的是類的屬性,值是不固定的,根據(jù)對(duì)象來確定
fieldy.get(pt1);
改field需要調(diào)用fieldy.set(obj,value);
Method類
getMethod(name,parameterytpes) //類名,方法參數(shù)類型
//執(zhí)行方法用invoke(obj,parameters)
Method methodCharAt=String.class.getMethod("charAt",int.class)
//靜態(tài)方法 name=null
methodCharAt.invoke(str1,1);
2 public class ReflectPoint {
3 private int x;
4 public int y;
5 public String str1="china";
6 public String str2="basketbool";
7 public String str3="itcast";
8 public ReflectPoint(int x, int y) {
9 super();
10 this.x = x;
11 this.y = y;
12 }
13
14 }
15
2 import java.lang.reflect.*;
3 public class ReflectTest {
4
5 /**反射基本知識(shí)
6 *
7 * 反射就是把java類中的各個(gè)成分映射為java類
8 * 反射的基礎(chǔ)是Class類,它是java類的描述類,Class類的實(shí)例是某個(gè)類的字節(jié)碼
9 * @param args
10 */
11 public static void main(String[] args) throws Exception {
12 // TODO Auto-generated method stub
13 //Class測試
14 //Class的實(shí)例是類的字節(jié)碼
15 String str1="abcde";
16
17 //獲取Class實(shí)例的三種方式
18 Class cls1= str1.getClass(); //獲取該對(duì)象類的字節(jié)碼
19 Class cls2=String.class; //直接調(diào)用類的字節(jié)碼
20 Class cls3=Class.forName("java.lang.String");//根據(jù)類名獲取字節(jié)碼
21
22 System.out.println(cls1==cls2); //true
23 System.out.println(cls1==cls3); //true
24
25 //isPrimitive()是否是基本數(shù)據(jù)類型的字節(jié)碼 8種+void
26 System.out.println(cls1.isPrimitive()); //false
27 System.out.println(Integer.class.isPrimitive());//false
28 System.out.println(int.class.isPrimitive()); //true
29
30 //Integer.TYPE常量 代表包裝的基本類型 的 字節(jié)碼
31 System.out.println(int.class==Integer.TYPE); //true
32
33 //數(shù)組不是基本數(shù)據(jù)類型,是對(duì)象
34 System.out.println(int[].class.isPrimitive()); //false
35 System.out.println(int[].class.isArray()); //true
36
37 //得到String類的 String(StringBuffer)構(gòu)造方法
38 Constructor constructor=String.class.getConstructor(StringBuffer.class);
39 //可以構(gòu)造方法,創(chuàng)建實(shí)例 ,并進(jìn)行類型轉(zhuǎn)換
40 String str2 = (String)constructor.newInstance(new StringBuffer("abcsd"));
41
42 ReflectPoint pt1=new ReflectPoint(3,5);
43
44 //Field類
45 Field fieldy=pt1.getClass().getField("y");
46 //fieldy的值是5嗎? 不是,fieldy不代表具體的值,只代表類的y變量
47 //因?yàn)槿〉氖穷惖淖止?jié)碼,類中變量的值是根據(jù) 對(duì)象來決定的
48 //通過.get(object) 來獲取某個(gè)對(duì)象的值
49 System.out.println(fieldy.get(pt1));
50
51 Field fieldx=pt1.getClass().getDeclaredField("x");//獲取聲明過的屬性
52 fieldx.setAccessible(true); //訪問權(quán)限設(shè)置為true
53 System.out.println(fieldx.get(pt1));
54
55 changeString(pt1);
56 System.out.println(pt1.str1);
57 System.out.println(pt1.str2);
58 System.out.println(pt1.str3);
59
60 //Method
61 //取得類字節(jié)碼 中的charAt方法
62 Method methodCharAt=String.class.getMethod("charAt", int.class);
63 //調(diào)用invoke(obj,parameter) 執(zhí)行方法
64 System.out.println(methodCharAt.invoke(str1,1));
65
66
67 //調(diào)用main()方法,普通方式
68 // TestArguments.main(new String[]{"abc","1111"});
69 //使用反射調(diào)用,為了解決,給定類名,而不知道實(shí)現(xiàn)代碼的情況下用
70 //從類字節(jié)碼 得到 main方法
71 Method methodmain=Class.forName(args[0]).getMethod("main",String[].class);
72 methodmain.invoke(null,new Object[]{new String[]{"abc","1111"}});
73
74 //數(shù)組的反射
75 int[] a1=new int[3];
76 int[] a2=new int[4];
77 int[][] a3=new int[2][3];
78 String[] a4=new String[2];
79 //數(shù)組的字節(jié)碼比較,看的是數(shù)組類型和數(shù)組維度
80 System.out.println(a1.getClass()==a2.getClass()); //true
81 System.out.println(a1.getClass()==a3.getClass()); //false
82 System.out.println(a1.getClass()==a4.getClass()); //false
83 System.out.println(a3.getClass()==a4.getClass()); //false
84 //獲取父類
85 System.out.println(a1.getClass().getName());
86 System.out.println(a1.getClass().getSuperclass().getName());
87 System.out.println(a4.getClass().getSuperclass().getName());
88 //得出父類都是Object類
89 Object aobj1=a1;
90 Object aobj2=a2;
91 Object aobj4=a4;
92 //Object[] aobj5=a1; //里面裝的是基本類型,基本類型不是對(duì)象,不能裝入
93 Object[] aobj5=a3;
94
95 int[] t1=new int[]{12,34,2};
96 printObject(t1); //打印對(duì)象,數(shù)組是對(duì)象,但t1數(shù)組元素是基本類型
97 printObject("xyz"); //打印對(duì)象
98
99 }
100
101 private static void printObject(Object obj){
102 Class clazz=obj.getClass(); //獲取該對(duì)象類的字節(jié)碼
103 if(clazz.isArray()){
104 //Array是數(shù)組的反射類
105 for(int i=0;i<Array.getLength(obj);i++){
106 System.out.println(Array.get(obj, i));
107 }
108 }else{
109 System.out.println(obj);
110 }
111 }
112
113 private static void changeString(Object obj){
114 Field[] fields=obj.getClass().getFields();
115 for(Field field:fields){
116 if(field.getType()==String.class){//同一份字節(jié)碼 用==
117 try {
118 String newValue=((String)field.get(obj)).replace('a', 'b');
119 field.set(obj, newValue);
120 } catch (Exception e) {
121 // TODO: handle exception
122 }
123 }
124 }
125 }
126 }
posted on 2010-12-29 13:21 杰點(diǎn) 閱讀(327) 評(píng)論(0) 編輯 收藏 所屬分類: JAVA