淺析JAVA反射(二)

上一篇介紹了java反射的基本概念,並通過一個簡單的例子展示瞭如何獲取一個類所定義的變量和方法
下面將介紹如何通過反射來訪問類裏面的方法,先看一個例子

  1. importjava.lang.reflect.AccessibleObject;
  2. importjava.lang.reflect.Field;
  3. importjava.lang.reflect.Method;
  4. publicclassTest{
  5. privateStringname;
  6. publicStringgetName(){
  7. returnname;
  8. }
  9. publicvoidsetName(Stringname){
  10. this.name=name;
  11. System.out.println("初始化name屬性:"+name);
  12. }
  13. publicstaticvoidmain(String[]args){
  14. System.out.println("show方法的輸出:");
  15. show(newTest());
  16. System.out.println("getSetMethod方法的輸出:");
  17. getSetMethod(newTest());
  18. }
  19. @SuppressWarnings("unchecked")
  20. publicstaticvoidshow(Objectclazz){
  21. try{
  22. /**
  23. *獲取類裏面的setName方法並指定其參數是String類型
  24. */
  25. MethodsetName=clazz.getClass().getMethod("setName",newClass[]{String.class});
  26. /**
  27. *調用setName方法,並指定參數爲"zhjb"
  28. */
  29. setName.invoke(clazz,"zhjb");
  30. /**
  31. *獲取類裏面的getName方法
  32. */
  33. MethodgetName=clazz.getClass().getMethod("getName");
  34. /**
  35. *調用getName方法,並打印其返回值
  36. */
  37. System.out.println(getName.invoke(clazz));
  38. }catch(Exceptione){
  39. e.printStackTrace();
  40. }
  41. }
  42. @SuppressWarnings("unchecked")
  43. publicstaticvoidgetSetMethod(Objectclazz){
  44. try{
  45. /**
  46. *得到定義的變量
  47. */
  48. Field[]field=clazz.getClass().getDeclaredFields();
  49. /**
  50. *設置訪問權限,即使是private也能訪問
  51. */
  52. AccessibleObject.setAccessible(field,true);
  53. /**
  54. *給該變量賦值
  55. */
  56. field[0].set(clazz,"zhjb");
  57. System.out.println(field[0].get(clazz));
  58. }catch(Exceptione){
  59. e.printStackTrace();
  60. }
  61. }
  62. }

運行上面的代碼輸出結果爲:

show方法的輸出:
初始化name屬性:zhjb
zhjb
getSetMethod方法的輸出:
zhjb

由輸出的結果可以看出,show方法裏面通過調用類裏面的set方法給變量name賦值,而getSetMethod方法裏面是直接對類裏面成員變量賦值,應爲AccessibleObject.setAccessible(field,true);這樣設置了訪問權限,那麼即使是private也能進行直接的賦值,但是這種方法並不是很好,破壞了JavaBean的規則,所以建議使用通過get 、set的方法來訪問Java類。上面的例子都寫了註釋了,就不在細說了。

下面看一個例子,就是把request裏面的參數根據名字封裝到一個JavaBean裏面

  1. /**
  2. *把request對象裏面的屬性拷貝到一個標準的JavaBean裏面,時間格式默認爲yyyy-MM-ddHH:mm:SS
  3. *因爲只是介紹反射的用法,所以本方法只是做演示,肯定有很多的BUG,Object裏面的屬性沒有自己定義的類
  4. *如果實際工程中可以使用org.apache.commons.beanutils.BeanUtils.copyProperties()方法
  5. *@paramobj
  6. *@paramrequest
  7. *@throwsParseException
  8. */
  9. @SuppressWarnings("unchecked")
  10. publicstaticvoidcopyProperties(Objectobj,HttpServletRequestrequest)throwsException{
  11. /**
  12. *得到定義的變量
  13. */
  14. Field[]field=obj.getClass().getDeclaredFields();
  15. Class[]clazz=newClass[1];
  16. for(Fieldf:field){
  17. Objectvalue=request.getParameter(f.getName());
  18. if(value==null){
  19. continue;
  20. }
  21. StringmethodName=getMethodName(f.getName());
  22. if(f.getType().getName().equals("java.util.Date")){
  23. SimpleDateFormatsf=newSimpleDateFormat("yyyy-MM-ddHH:mm:SS");
  24. value=sf.parse(value.toString());
  25. clazz[0]=Date.class;
  26. }elseif(f.getType().getName().equals(Integer.class.getName())){
  27. clazz[0]=Integer.class;
  28. value=newInteger(value.toString());
  29. }elseif(f.getType().getName().equals(String.class.getName())){
  30. clazz[0]=String.class;
  31. }
  32. Methodmethod=obj.getClass().getDeclaredMethod(methodName,clazz);
  33. method.invoke(obj,value);
  34. }
  35. }
  36. /**
  37. *把屬性的第一個字母變爲大寫,然後在前面加上set,給該屬性賦值,這是JavaBean的標準命名規則
  38. *@paramfieldName
  39. */
  40. publicstaticStringgetMethodName(StringfieldName){
  41. charc=fieldName.charAt(0);
  42. if(c>='a'&&c<='z'){
  43. c=(char)(c-'a'+'A');
  44. }
  45. return"set"+c+fieldName.substring(1);
  46. }

注:Java裏面的屬性必須是對象,有代碼就可以去看如何實現了

發佈了0 篇原創文章 · 獲贊 0 · 訪問量 2778
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章