Java循環一個對象的所有屬性,並通過反射給這些屬性賦值/取值


Java循環一個對象的所有屬性,並通過反射給這些屬性賦值/取值

說到循環遍歷,最常見的遍歷數組/列表、Map等。但是,在開發過程中,有時需要循環遍歷一個對象的所有屬性。遍歷對象的屬性該如何遍歷呢?查了一下資料,需要用到一些反射的知識!

話不多說,先上代碼

首先先定義一個測試對象 Test

public class Test { private String aa; private int bb; private String cc; public String dd; public String getAa() { return aa; } public void setAa(String aa) { this.aa = aa; } public int getBb() { return bb; } public void setBb(int bb) { this.bb = bb; } public String getCc() { return cc; } public void setCc(String cc) { this.cc = cc; } }

這個對象里分別有aa bb cc 三個私有屬性,dd一個公有屬性,接下來通過反射來獲取這個對象的四個屬性值

    public static void main(String[] args) { /** * 返回Class 對象所表示的類或接口的所有可訪問公共字段。 */ Field[] f1=Test.class.getFields(); System.out.println("Test類里面的公共字段屬性的個數為:" +f1.length+"個,分別為:"); for(int i=0;i<f1.length;i++){ String attributeName=f1[i].getName(); System.out.println(attributeName); } /** * 返回 Class 對象所表示的類或接口所聲明的所有字段, * 包括公共、保護、默認(包)訪問和私有字段,但不包括繼承的字段。 */ Field[] f=Test.class.getDeclaredFields(); System.out.println("Test類里面的所有字段屬性的個數為:"+f.length+"個,分別為:"); for(int i=0;i<f.length;i++){ String attributeName=f[i].getName(); System.out.println(attributeName); } }

運行main函數,輸出如下:

Test類里面的公共字段屬性的個數為:1個,分別為: 
dd 
Test類里面的所有字段屬性的個數為:4個,分別為: 
aa 
bb 
cc 
dd

getFields()方法只能獲取Test類里面的所有公有屬性,getDeclaredFields()方法可獲取Test類所有公有/私有屬性。需要注意的是,如果Test類繼承了別的類,這兩個方法都無法獲取父類里面的屬性的。

現在,已經獲取到了Test類里面的所有屬性名,然后通過這些屬性名給這個類的實例賦值和取值操作。

先來給實例賦值,代碼如下:

        Test test=new Test(); //給test對象賦值 for(int i=0;i<f.length;i++){ //獲取屬相名 String attributeName=f[i].getName(); //將屬性名的首字母變為大寫,為執行set/get方法做准備 String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1); try{ //獲取Test類當前屬性的setXXX方法(私有和公有方法) /*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/ //獲取Test類當前屬性的setXXX方法(只能獲取公有方法) Method setMethod=Test.class.getMethod("set"+methodName,String.class); //執行該set方法 setMethod.invoke(test,attributeName+"方法賦值"); }catch (NoSuchMethodException e) { try { Method setMethod=Test.class.getMethod("set"+methodName,int.class); setMethod.invoke(test,123); } catch (Exception e2) { f[i].set(test,attributeName+"直接賦值"); } } } 

如上代碼,之前已經獲取到了Test類里面的所有屬性名,在這部分代碼中,就可以通過屬性名來獲取與之對應的set方法。需要注意的是,在上面代碼中try-catch了兩次,是因為在Test這個類中的屬性的set方法的參數,有的是String類型,有的是int類型的,還有的屬性是沒有set方法的。第一次try是未了抓取所有參數類型不是String類型和不存在的set方法。第二次抓取的是參數不是int類型的和不存在的set方法。依次進行處理。除此之外,假如set方法的參數類型還有更多的類型的話,可以通過Filed類的getGenericType() 這個方法先判斷類型,這個以后再做贅述。

接下來從實例中通過get方法來取值,代碼如下:

        //從test對象取值 for(int i=0;i<f.length;i++){ //獲取屬相名 String attributeName=f[i].getName(); //將屬性名的首字母變為大寫,為執行set/get方法做准備 String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1); Object result; try{ //獲取Test類當前屬性的setXXX方法(私有和公有方法) /*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/ //獲取Test類當前屬性的setXXX方法(只能獲取公有方法) Method getMethod=Test.class.getMethod("get"+methodName); //執行該set方法 result=getMethod.invoke(test); }catch(NoSuchMethodException e){ result=f[i].get(test); } System.out.println("屬性:"+attributeName+"="+result); }

這里的代碼也try-catch一次,get方法不存在參數類型判斷的,這里的try-catch只是為了抓取公有屬性不存在get方法的情況以做相應的處理。

運行測試程序,輸出結果如下:

屬性:aa=aa方法賦值 
屬性:bb=123 
屬性:cc=cc方法賦值 
屬性:dd=dd直接賦值

最后附上完整的測試程序

    public static void main(String[] args) throws Exception{ /** * 返回Class 對象所表示的類或接口的所有可訪問公共字段。 */ Field[] f1=Test.class.getFields(); System.out.println("Test類里面的公共字段屬性的個數為:" +f1.length+"個,分別為:"); for(int i=0;i<f1.length;i++){ String attributeName=f1[i].getName(); System.out.println(attributeName); } /** * 返回 Class 對象所表示的類或接口所聲明的所有字段, * 包括公共、保護、默認(包)訪問和私有字段,但不包括繼承的字段。 */ Field[] f=Test.class.getDeclaredFields(); System.out.println("Test類里面的所有字段屬性的個數為:"+f.length+"個,分別為:"); for(int i=0;i<f.length;i++){ String attributeName=f[i].getName(); System.out.println(attributeName); } Test test=new Test(); //給test對象賦值 for(int i=0;i<f.length;i++){ //獲取屬相名 String attributeName=f[i].getName(); //將屬性名的首字母變為大寫,為執行set/get方法做准備 String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1); try{ //獲取Test類當前屬性的setXXX方法(私有和公有方法) /*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/ //獲取Test類當前屬性的setXXX方法(只能獲取公有方法) Method setMethod=Test.class.getMethod("set"+methodName,String.class); //執行該set方法 setMethod.invoke(test,attributeName+"方法賦值"); }catch (NoSuchMethodException e) { try { Method setMethod=Test.class.getMethod("set"+methodName,int.class); setMethod.invoke(test,123); } catch (Exception e2) { f[i].set(test,attributeName+"直接賦值"); } } } //從test對象取值 for(int i=0;i<f.length;i++){ //獲取屬相名 String attributeName=f[i].getName(); //將屬性名的首字母變為大寫,為執行set/get方法做准備 String methodName=attributeName.substring(0,1).toUpperCase()+attributeName.substring(1); Object result; try{ //獲取Test類當前屬性的setXXX方法(私有和公有方法) /*Method setMethod=Test.class.getDeclaredMethod("set"+methodName);*/ //獲取Test類當前屬性的setXXX方法(只能獲取公有方法) Method getMethod=Test.class.getMethod("get"+methodName); //執行該set方法 result=getMethod.invoke(test); }catch(NoSuchMethodException e){ result=f[i].get(test); } System.out.println("屬性:"+attributeName+"="+result); } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM