1. 程式人生 > >反射實現物件的封裝

反射實現物件的封裝

       近期在專案中收到socket接收到的報文,將每個月的資料整理成符合json格式的資料,從前臺傳到後臺生成pdf,其中涉及到了一個方法,我希望在此記錄下,因為比較實用。

      先說說為什麼要轉吧?接受到的報文大致是這樣的{property="12".......,list=[propert2="",........],propert3="",........]....},大概是這麼一個模式,就是返回一個returnMap,包含了報文頭以及迴圈的資訊,二迴圈的資訊依然是個Map,只不過泛型是<String,List<Dto>>,我要做的就是遍歷這個含有List的Map<String,List<Dto>>,然後一一將單個集合轉化為一個實體,我院額原本的資料來源是{"1806":["":"",...],"1806":["":"",...]} ,這是前臺傳來的Json字串,後臺我將它轉為Map,實現了物件的封裝,現在就用程式碼 實現它吧!因為資料比較冗長,我做了有幾個demo用於觀察。

//那麼如何將一個map<String,Object> 的型別轉為一個物件呢?當然其中的方法很多,但最簡潔的還是用反射去實現最為方便。看了我們經理寫的,具有參考價值。

//第一步:先製造幾個假的資料和幾個需要用到的實體類
public static void main(Stirng[] args){
    Map<String,Object> map = new HashMap<String,Object>();
    List<StringDto> list = new ArrayList<StringDto>();
    StringDto dto = new StringDto();
    dto.set("a");dto.set("b");dto.set("c");
    list.add(dto);
    map.put("name","胡明明");map.put("age","25");map.put("list","list");
    //這裡資料就整合完了,就是map包含了兩個字串和一個集合然後用一個實體類去拿到map的資料,實體類我就不做展示了
    ResDto resDto = new ResDto();//資料可以比map中的資料少,多則為null或“”,因為是從map中拿資料去填充這個響應的實體類
    FanShe(map,resDto);
    System.out.println(resDto);//resDto 重寫了toString()方法
}

//第二步,將單個map的屬性轉為實體類屬性
public void static FanShe(Map<String,Object> map,Obejct obj){
    Class<?> cl = obj.getClass();
    Field[] fields = cl.getDeclaredFields();//取得反射物件的所有屬性
    for(int i=0;i<fields.length;i++){
        //篩選屬性為private的屬性
        int number = fields[i].getModifiers();//返回修飾符的int
        String str = Modifier.toString(number);//對類和成員的訪問修飾符進行解碼
        if("private".equals(str)){
            String property = fields[i].getName();//取得為private修飾字段的名稱
            if(map.containsKey(property)){
                Class<?> mapObjClass = map.get(property).getClass();//取得map中value的反射物件
                Class<?>[] interfaceAry = mapObjClass.getInterface();//取得該類實現的介面,比如String類就[interface java.io.serializable,interface java.lang.Compable,]            
                Class<?> singleInterface = null;
                for(int j=0;j<interfaceAry .length,j++){
                    if(interfaceAry[j].equals(List.class.getName)){//java.io.serializable
                        singleInterface = interfaceAry[j];
                        break;
                    }
                }
                //因為Map中包含了List的話,去調mapObjClass.getDeclaredMethod方法時,引數的反射型別是介面型別,而不是ArrayList類型別
                if(null != singleInterface){
                    Method method = mapObjClass.getDeclaredMethod(getFuncName(property),singleInterface);
                }else{
                   Method method =  mapObjClass.getDeclaredMethod(getFuncName(property),mapObjClass);
                }
                Method.invoke(obj,map.get(property));//(呼叫底層的方法物件,該方法形參引數型別  類似於物件.方法  如果沒有引數的話則第二個引數不填mapObjClass.getDeclaredMethod(getFuncName(property));
            }
        }  

    }
}

public static String getFuncName(String propertyStr){
    String funcNameStr = "set" + propertyStr.substring(0,1).toUpperCase() + propertyStr.substring(1);
    return funcNameStr; 
}