andy-j2ee |
|
|||
JAVA |
公告
日歷
統(tǒng)計(jì)
導(dǎo)航常用鏈接留言簿隨筆分類(lèi)(5)隨筆檔案(19)文章分類(lèi)(1)文章檔案(1)搜索最新評(píng)論
閱讀排行榜評(píng)論排行榜 |
以前一直只知道有reflect這么一個(gè)類(lèi)是用來(lái)反射的,聽(tīng)人家說(shuō)java中的反射很難,晚上聽(tīng)罷張老師講的反射這一節(jié)的內(nèi)容,惶然大悟,原來(lái)反射就是把Java類(lèi)中的各種成分映射成相應(yīng)的java類(lèi)。
反射的基礎(chǔ)是要掌握Class這個(gè)類(lèi)的,具體Class的類(lèi)是干什么的,下面是api文檔中的解釋 可以看出Class類(lèi)就是一個(gè)類(lèi)或者接口對(duì)象的一個(gè)實(shí)例在內(nèi)存中的字節(jié)碼,而如何得到一個(gè)類(lèi)的字節(jié)碼呢?其方法有三: 1 Class<? extends String> cls1 = str1.getClass();
而Class的isPrimitive()方法就是用來(lái)判斷一個(gè)類(lèi)的字節(jié)碼是不是9個(gè)預(yù)定義的class2 Class<String> cls2 = String.class; 3 Class<?> cls3 = Class.forName("java.lang.String"); 接下來(lái)是Constructor類(lèi),Constructor類(lèi)代表某個(gè)類(lèi)中的一個(gè)構(gòu)造方法。 得到某個(gè)類(lèi)所有的構(gòu)造方法: 例子: Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
得到某一個(gè)構(gòu)造方法:
例子: Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//獲得方法時(shí)要用到類(lèi)型 創(chuàng)建實(shí)例對(duì)象: //通常方式: String str = new String(new StringBuffer("abc")); //反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));//調(diào)用獲得的方法時(shí)要用到上面相同類(lèi)型的實(shí)例對(duì)象 Class.newInstance()方法: 例子: String obj = (String)Class.forName("java.lang.String").newInstance(); 該方法內(nèi)部先得到默認(rèn)的構(gòu)造方法,然后用該構(gòu)造方法創(chuàng)建實(shí)例對(duì)象。 該方法內(nèi)部的具體代碼是怎樣寫(xiě)的呢?用到了緩存機(jī)制來(lái)保存默認(rèn)構(gòu)造方法的實(shí)例對(duì)象。 下面是一個(gè)Field反射的綜合實(shí)例 將任意一個(gè)對(duì)象中的所有String類(lèi)型的成員變量所對(duì)應(yīng)的字符串內(nèi)容中的"b"改成"a"。 首先定義一個(gè)ReflectPoint的類(lèi) 1 package com.anduo.day1; 2 3 public class ReflectPoint { 4 private int x; 5 public int y; 6 public String a = "ball"; 7 public String b = "basketball"; 8 public String c = "hello"; 9 10 public ReflectPoint(int x, int y) { 11 super(); 12 this.x = x; 13 this.y = y; 14 } 15 16 @Override 17 public String toString() { 18 return "a=" + a + ";b=" + b + ";c=" + c; 19 } 20 } 21 下面的步驟是:先從對(duì)象中得到所有為String類(lèi)型的字段,2:得到Sting字段的值;3:用String類(lèi)的replace方法代換a字符為b字符;4:把對(duì)象的String字段設(shè)置為修改完的新String。 齊活兒 1 package com.anduo.day1; 結(jié)果如下2 3 import java.lang.reflect.Constructor; 4 import java.lang.reflect.Field; 5 6 public class ReflectTest { 7 8 9 public static void main(String[] args) throws Exception { 10 11 12 /** 13 * 成員變量的反射 Field 14 */ 15 System.out.println("**成員變量的反射 Field**"); 16 ReflectPoint pt1 = new ReflectPoint(1, -1); 17 Field fieldY = pt1.getClass().getField("y"); 18 // fieldY 不是對(duì)象身上的變量,而是類(lèi)上,要用它來(lái)去對(duì)象上字段的值 19 System.out.println("p1 中 y = " + fieldY.get(pt1)); 20 Field fieldX = pt1.getClass().getDeclaredField("x");// 獲取私有屬性字段 21 fieldX.setAccessible(true);// 暴力反射 22 System.out.println("p1 中 x = " + fieldX.get(pt1)); 23 24 /** 25 * 將任意一個(gè)對(duì)象中的所有String類(lèi)型的成員變量所對(duì)應(yīng)的字符串內(nèi)容中的"b"改成"a" 26 */ 27 changeStringValue(pt1); 28 System.out.println(pt1); 29 } 30 31 /** 32 * 將任意一個(gè)對(duì)象中的所有String類(lèi)型的成員變量所對(duì)應(yīng)的字符串內(nèi)容中的"b"改成"a" 33 * @param obj 34 * @throws IllegalArgumentException 35 * @throws IllegalAccessException 36 */ 37 private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException { 38 Field[] fields = obj.getClass().getFields(); 39 for (Field field : fields) { 40 // if(field.getType().equals(String.class)) 41 if (field.getType() == String.class) { 42 String oldValue = (String) field.get(obj); 43 String newValue = oldValue.replace('a', 'b'); 44 field.set(obj, newValue); 45 } 46 } 47 } 48 49 } 50 **成員變量的反射 Field** p1 中 y = -1 p1 中 x = 1 a=bbll;b=bbsketbbll;c=hello 綜上可以看出,其實(shí)反射也沒(méi)多難,人家那些寫(xiě)框架的也不就是用了些反射嗎?把配置文件中的東西讀出來(lái),然后再調(diào)用下面的類(lèi)去做應(yīng)該做的事情,當(dāng)然這個(gè)過(guò)程就用到了反射了。
|
![]() |
|
Copyright © 安多 | Powered by: 博客園 模板提供:滬江博客 |