andy-j2ee |
|
|||
JAVA |
公告
日歷
統計
導航常用鏈接留言簿隨筆分類(5)隨筆檔案(19)文章分類(1)文章檔案(1)搜索最新評論
閱讀排行榜評論排行榜 |
以前一直只知道有reflect這么一個類是用來反射的,聽人家說java中的反射很難,晚上聽罷張老師講的反射這一節的內容,惶然大悟,原來反射就是把Java類中的各種成分映射成相應的java類。
反射的基礎是要掌握Class這個類的,具體Class的類是干什么的,下面是api文檔中的解釋 可以看出Class類就是一個類或者接口對象的一個實例在內存中的字節碼,而如何得到一個類的字節碼呢?其方法有三: 1 Class<? extends String> cls1 = str1.getClass();
而Class的isPrimitive()方法就是用來判斷一個類的字節碼是不是9個預定義的class2 Class<String> cls2 = String.class; 3 Class<?> cls3 = Class.forName("java.lang.String"); 接下來是Constructor類,Constructor類代表某個類中的一個構造方法。 得到某個類所有的構造方法: 例子: Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
得到某一個構造方法:
例子: Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//獲得方法時要用到類型 創建實例對象: //通常方式: String str = new String(new StringBuffer("abc")); //反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));//調用獲得的方法時要用到上面相同類型的實例對象 Class.newInstance()方法: 例子: String obj = (String)Class.forName("java.lang.String").newInstance(); 該方法內部先得到默認的構造方法,然后用該構造方法創建實例對象。 該方法內部的具體代碼是怎樣寫的呢?用到了緩存機制來保存默認構造方法的實例對象。 下面是一個Field反射的綜合實例 將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"b"改成"a"。 首先定義一個ReflectPoint的類 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 下面的步驟是:先從對象中得到所有為String類型的字段,2:得到Sting字段的值;3:用String類的replace方法代換a字符為b字符;4:把對象的String字段設置為修改完的新String。 齊活兒 1 package com.anduo.day1; 結果如下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 不是對象身上的變量,而是類上,要用它來去對象上字段的值 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 * 將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"b"改成"a" 26 */ 27 changeStringValue(pt1); 28 System.out.println(pt1); 29 } 30 31 /** 32 * 將任意一個對象中的所有String類型的成員變量所對應的字符串內容中的"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 綜上可以看出,其實反射也沒多難,人家那些寫框架的也不就是用了些反射嗎?把配置文件中的東西讀出來,然后再調用下面的類去做應該做的事情,當然這個過程就用到了反射了。 |
![]() |
|
Copyright © 安多 | Powered by: 博客園 模板提供:滬江博客 |