Java反射应用实例_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java反射应用实例

Java反射应用实例

 2012/1/19 9:12:24  hejiangtao  程序员俱乐部  我要评论(0)
  • 摘要:本文主要通过Java反射应用实例来讲解利用反射方法创建对象(使用默认构造函数和自定义构造函数),访问对应对象的方法(包括带参数的和不带参数的),访问对应对象的域(Field).从这里可以下载到完整的java代码工程:http://download.csdn.net/detail/hejiangtao/4011663很多IOC等框架都使用反射来实现,例如Spring,Hibernate等,Java反射的方式实现的逻辑比普通类逻辑的效率是要差一些的(14至300倍左右)
  • 标签:Java 应用 反射 实例

本文主要通过Java反射应用实例来讲解 利用反射方法创建对象(使用默认构造函数自定义构造函数) ,访问对应对象的方法(包括带参数的和不带参数的),访问对应对象的域(Field) . 从 这里 可以下载到完整的java代码工程: ? http://download.csdn.net/detail/hejiangtao/4011663

很多IOC等框架都使用反射来实现,例如Spring, Hibernate等, Java反射的方式实现的逻辑比普通类逻辑的效率是要差一些的(14至300倍左右), 具体可以参考我转载的一篇文章<java反射的性能问题 >http://blog.csdn.net/hejiangtao/article/details/7188835.

首先看下我们实例中被访问的类DataTypeBean.java:

这个Bean中定义了4种类型的Field,包含了int, String,String数组和List; 定义了默认构造函数和自定义的构造函数; 还有一个给List域赋值的带参数函数; 一个不带参数的toString函数.我们要实现的就是使用反射的方法来访问这些Fields 和Methods.

?

[html] view plain copy
  1. package?com.ross.reflect.bean;??
  2. import?java.util.*;??
  3. /**??
  4. ?*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
  5. ?*?Date:?2012-1-4??
  6. ?*?Since:?MyJavaExpert?v1.0??
  7. ?*?Description:?It?will?contains?some?typical?fields?whose?data?types??
  8. ?*???are?using?frequently.?it?will?be?used?in?the?reflect?test??
  9. ?*/??
  10. public?class?DataTypeBean??
  11. {??
  12. ????private?int?iInt;??
  13. ????private?String?sStr;??
  14. ????private?String[]?saStr;??
  15. ????List< Integer > ?oList;??
  16. ??
  17. ????//?default?constructor??
  18. ????public?DataTypeBean()??
  19. ????{??
  20. ????}??
  21. ??
  22. ????//?constructor?with?parameters??
  23. ????public?DataTypeBean(int?iInt,?String?sStr,?String[]?saStr,??
  24. ????????????List< Integer > ?oList)??
  25. ????{??
  26. ????????this.iInt ?=?iInt;??
  27. ????????this.saStr ?=?saStr;??
  28. ????????this.sStr ?=?sStr;??
  29. ????????this.oList ?=?oList;??
  30. ????}??
  31. ??
  32. ????//?method?with?parameter,?it?will?set?value?of?the?list?field??
  33. ????public?void?addDataToList(int?iStart,?int?iEnd)??
  34. ????{??
  35. ????????if?(iStart?< ? iEnd )??
  36. ????????{??
  37. ????????????oList ?=? new ?ArrayList < Integer > ();??
  38. ????????????while?(iStart?< =?iEnd)??
  39. ????????????{??
  40. ????????????????oList.add(iStart);??
  41. ????????????????iStart++;??
  42. ????????????}??
  43. ????????}??
  44. ????}??
  45. ??
  46. ????//?method?without?parameter??
  47. ????public?String?toString()??
  48. ????{??
  49. ????????StringBuffer?sbStr ?=? new ?StringBuffer();??
  50. ????????sbStr.append("Values?of?the?fields?of?DataTypeBean:?iInt ?=?");??
  51. ????????sbStr.append(this.iInt).append("?;?");??
  52. ????????for?(int?i ?=? 0 ;?i? < ? this.saStr.length ;?i++)??
  53. ????????{??
  54. ????????????sbStr.append("saStr").append("[").append(i).append("]").append(??
  55. ????????????????????"?=?").append(saStr[i]).append("?;?");??
  56. ????????}??
  57. ??
  58. ????????for?(int?j ?=? 0 ;?j? < ? this.oList.size ();?j++)??
  59. ????????{??
  60. ????????????sbStr.append("oList.get").append("(").append(j).append(")").append(??
  61. ????????????????????"?=?").append(oList.get(j)).append("?;?");??
  62. ????????}??
  63. ????????return?sbStr.toString();??
  64. ????}??
  65. ??
  66. ????//省略了set/get方法??
  67. }??

来看我们的反射的实现类MyReflect.java, 由于担心代码太长不好看,就全部在Main函数里面写了,方便看.

1. 首先我们看下使用默认构造函数创建类对象, 并通过访问Field对象来给类对象赋值, 最后通过toString方法打印字符串.

初始化我们要使用的参数, 这些参数将用于给类的Field赋值:

[html] view plain copy
  1. int? iInt ?=? 2012 ;??
  2. String?sStr ?=? "This?a?string!" ;??
  3. String[]?saStr ?=? new ?String[]?{?"First?item?of?the?string?array",??
  4. ????????"Second?item?of?the?string?array",??
  5. ????????"Third?item?of?the?string?array"?};??
  6. List< Integer > ? oList ?=? new ?ArrayList < Integer > ();??
  7. ??
  8. //?Initialize?the?oList??
  9. int?i ?=? 0 ;??
  10. while?(i?< ? 3 )??
  11. {??
  12. ????oList.add(i);??
  13. ????i++;??
  14. }??
获取 DataTypeBean的类,和我们将要用到的方法对象, 其中toString方法是不带参数的,addDataToList则是带参数的. 由此可以看出我们在使用反射方法的时候是需要知道参数个数和参数类型的: [html] view plain copy
  1. //?get?class??
  2. Class?oClass ?=?Class.forName("com.ross.reflect.bean.DataTypeBean");??
  3. //?get?the?toString?method,?a?method?without?parameters??
  4. Method?oToStringMethod ?=? oClass .getMethod("toString");??
  5. //?get?the?addDataToList?method,?a?method?with?parameters??
  6. Method?oAddDataToListMethod ?=? oClass .getMethod("addDataToList",??
  7. ????????int.class,?int.class);??
使用默认构造函数创建一个 DataTypeBean的对象: [html] view plain copy
  1. //?used?default?constructor?to?initialize?a?object??
  2. Object?oDefalutObject ?=? oClass .newInstance();??
使用反射方法访问Field来给对象赋值: [html] view plain copy
  1. //?access?fields?process,?getDeclaredFields?can?access?private?and??
  2. //?protected?fields??
  3. Field[]?oFields ?=? oClass .getDeclaredFields();??
  4. for?(int?j ?=? 0 ;?j? < ? oFields.length ;?j++)??
  5. {??
  6. ????//?to?access?the?private??
  7. ????oFields[j].setAccessible(true);??
  8. ??
  9. ????//?getSimpleName?method?can?get?the?type?of?the?field,?according?the??
  10. ????//?field?type?set?the?data?to?the?field??
  11. ????if?("int".equals(oFields[j].getType().getSimpleName()))??
  12. ????{??
  13. ????????oFields[j].setInt(oDefalutObject,?iInt);??
  14. ????}??
  15. ????else?if?("String[]".equals(oFields[j].getType().getSimpleName()))??
  16. ????{??
  17. ????????oFields[j].set(oDefalutObject,?saStr);??
  18. ????}??
  19. ????else?if?("String".equals(oFields[j].getType().getSimpleName()))??
  20. ????{??
  21. ????????oFields[j].set(oDefalutObject,?sStr);??
  22. ????}??
  23. ????else?if?("List".equals(oFields[j].getType().getSimpleName()))??
  24. ????{??
  25. ????????oFields[j].set(oDefalutObject,?oList);??
  26. ????}??
  27. }??
通过反射方法调用 DataTypeBean的toString方法将赋值后的 DataTypeBean打印出来: [html] view plain copy
  1. //?print?the?object??
  2. String?sBeanString ?=?(String)?oToStringMethod.invoke(oDefalutObject);??
  3. System.out??
  4. ????????.println("the?string?of?the?object?created?by?defaut?constructor:?"??
  5. ????????????????+?sBeanString);??
运行后,我们的控制台打印出如下信息: [html] view plain copy
  1. the?string?of?the?object?created?by?defaut?constructor:?Values?of?the?fields?of?DataTypeBean:? iInt ?=? 2012 ?;???
  2. saStr[0]?=?First?item?of?the?string?array?;?saStr[1]?=?Second?item?of?the?string?array?;?saStr[2]?=?Third?item???
  3. of?the?string?array?;?oList.get(0)?=?0?;?oList.get(1)?=?1?;?oList.get(2)?=?2?;???

2. 我们再看下使用自定义构造函数创建类对象, 并通过带参数的函数给其List域赋值, 最后通过toString方法打印字符串.

变更下我们要用的参数, 好在控制台上跟默认构造函数创建的对象的打印信息做区分:

[html] view plain copy
  1. //?initialize?the?parameters?for?customized?constructor,?the?oList?will??
  2. //?be?initialized?by?the?method?with?parameters??
  3. iInt ?=? 2013 ;??
  4. sStr ?=? "This?another?string!" ;??
  5. saStr ?=? new ?String[]?{?"1st?item?of?the?string?array",??
  6. ????????"2nd?item?of?the?string?array",?"3rd?item?of?the?string?array"?};??
  7. oList ?=? new ?ArrayList < Integer > ();??
使用自定义构造函数创建类对象: [html] view plain copy
  1. //?used?customized?constructor?to?initialize?a?object:?DataTypeBean(int??
  2. //?iInt,?String?sStr,?String[]?saStr,?List< Integer > ?oList)??
  3. Constructor?oCon ?=? oClass .getConstructor(int.class,?String.class,??
  4. ????????String[].class,?List.class);??
  5. Object?oCustomizedObject ?=? oCon .newInstance(iInt,?sStr,?saStr,?oList);??
使用带参数的函数给List 域赋值: [html] view plain copy
  1. //Use?the?method?with?parameters?initialize?the?List?Object??
  2. ?oAddDataToListMethod.invoke(oCustomizedObject,2013,2015);??
同样的,通过反射方法调用 DataTypeBean的toString方法将赋值后的 DataTypeBean打印出来:
[html] view plain copy
  1. //?print?the?object??
  2. ???????sBeanString ?=?(String)?oToStringMethod.invoke(oCustomizedObject);??
  3. ???????System.out??
  4. ???????????????.println("the?string?of?the?object?created?by?customized?constructor:?"??
  5. ???????????????????????+?sBeanString);??
运行后,我们的控制台打印如下信息: [html] view plain copy
  1. the?string?of?the?object?created?by?customized?constructor:?Values?of?the?fields?of?DataTypeBean:? iInt ?=? 2013 ?;???
  2. saStr[0]?=?1st?item?of?the?string?array?;?saStr[1]?=?2nd?item?of?the?string?array?;?saStr[2]?=?3rd?item?of?the??
  3. ?string?array?;?oList.get(0)?=?2013?;?oList.get(1)?=?2014?;?oList.get(2)?=?2015?;?oList.get(3)?=?2016?;???

为了方便参考,我将完整的MyReflect.java贴出来了:

?

[html] view plain copy
  1. package?com.ross.reflect;??
  2. import?java.lang.reflect.Constructor;??
  3. import?java.lang.reflect.Field;??
  4. import?java.lang.reflect.InvocationTargetException;??
  5. import?java.lang.reflect.Method;??
  6. import?java.util.ArrayList;??
  7. import?java.util.List;??
  8. /**??
  9. ?*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
  10. ?*?Date:?2012-1-9??
  11. ?*?Since:?MyJavaExpert?v1.0??
  12. ?*?Description:?reflect?method?implementation?and?test??
  13. ?*/??
  14. public?class?MyReflect??
  15. {??
  16. ????/**??
  17. ?????*?Author:?Jiangtao?He;?Email:?ross.jiangtao.he@gmail.com??
  18. ?????*?Date:?2012-1-9???
  19. ?????*?Description:?Use?reflect?method?to?access?the?fields?and?methods?of?DataTypebean??
  20. ?????*/??
  21. ????public?static?void?main(String[]?args)?throws?ClassNotFoundException,??
  22. ????????????SecurityException,?NoSuchMethodException,?InstantiationException,??
  23. ????????????IllegalAccessException,?IllegalArgumentException,??
  24. ????????????InvocationTargetException??
  25. ????{??
  26. ????????int?iInt ?=? 2012 ;??
  27. ????????String?sStr ?=? "This?a?string!" ;??
  28. ????????String[]?saStr ?=? new ?String[]?{?"First?item?of?the?string?array",??
  29. ????????????????"Second?item?of?the?string?array",??
  30. ????????????????"Third?item?of?the?string?array"?};??
  31. ????????List< Integer > ? oList ?=? new ?ArrayList < Integer > ();??
  32. ??
  33. ????????//?Initialize?the?oList??
  34. ????????int?i ?=? 0 ;??
  35. ????????while?(i?< ? 3 )??
  36. ????????{??
  37. ????????????oList.add(i);??
  38. ????????????i++;??
  39. ????????}??
  40. ????????//?get?class??
  41. ????????Class?oClass ?=?Class.forName("com.ross.reflect.bean.DataTypeBean");??
  42. ????????//?get?the?toString?method,?a?method?without?parameters??
  43. ????????Method?oToStringMethod ?=? oClass .getMethod("toString");??
  44. ????????//?get?the?addDataToList?method,?a?method?with?parameters??
  45. ????????Method?oAddDataToListMethod ?=? oClass .getMethod("addDataToList",??
  46. ????????????????int.class,?int.class);??
  47. ??
  48. ????????//?used?default?constructor?to?initialize?a?object??
  49. ????????Object?oDefalutObject ?=? oClass .newInstance();??
  50. ??
  51. ????????//?access?fields?process,?getDeclaredFields?can?access?private?and??
  52. ????????//?protected?fields??
  53. ????????Field[]?oFields ?=? oClass .getDeclaredFields();??
  54. ????????for?(int?j ?=? 0 ;?j? < ? oFields.length ;?j++)??
  55. ????????{??
  56. ????????????//?to?access?the?private??
  57. ????????????oFields[j].setAccessible(true);??
  58. ??
  59. ????????????//?getSimpleName?method?can?get?the?type?of?the?field,?according?the??
  60. ????????????//?field?type?set?the?data?to?the?field??
  61. ????????????if?("int".equals(oFields[j].getType().getSimpleName()))??
  62. ????????????{??
  63. ????????????????oFields[j].setInt(oDefalutObject,?iInt);??
  64. ????????????}??
  65. ????????????else?if?("String[]".equals(oFields[j].getType().getSimpleName()))??
  66. ????????????{??
  67. ????????????????oFields[j].set(oDefalutObject,?saStr);??
  68. ????????????}??
  69. ????????????else?if?("String".equals(oFields[j].getType().getSimpleName()))??
  70. ????????????{??
  71. ????????????????oFields[j].set(oDefalutObject,?sStr);??
  72. ????????????}??
  73. ????????????else?if?("List".equals(oFields[j].getType().getSimpleName()))??
  74. ????????????{??
  75. ????????????????oFields[j].set(oDefalutObject,?oList);??
  76. ????????????}??
  77. ????????}??
  78. ??
  79. ????????//?print?the?object??
  80. ????????String?sBeanString ?=?(String)?oToStringMethod.invoke(oDefalutObject);??
  81. ????????System.out??
  82. ????????????????.println("the?string?of?the?object?created?by?defaut?constructor:?"??
  83. ????????????????????????+?sBeanString);??
  84. ??
  85. ????????//?initialize?the?parameters?for?customized?constructor,?the?oList?will??
  86. ????????//?be?initialized?by?the?method?with?parameters??
  87. ????????iInt ?=? 2013 ;??
  88. ????????sStr ?=? "This?another?string!" ;??
  89. ????????saStr ?=? new ?String[]?{?"1st?item?of?the?string?array",??
  90. ????????????????"2nd?item?of?the?string?array",?"3rd?item?of?the?string?array"?};??
  91. ????????oList ?=? new ?ArrayList < Integer > ();??
  92. ??
  93. ????????//?used?customized?constructor?to?initialize?a?object:?DataTypeBean(int??
  94. ????????//?iInt,?String?sStr,?String[]?saStr,?List< Integer > ?oList)??
  95. ????????Constructor?oCon ?=? oClass .getConstructor(int.class,?String.class,??
  96. ????????????????String[].class,?List.class);??
  97. ????????Object?oCustomizedObject ?=? oCon .newInstance(iInt,?sStr,?saStr,?oList);??
  98. ????????//Use?the?method?with?parameters?initialize?the?List?Object??
  99. ????????oAddDataToListMethod.invoke(oCustomizedObject,2013,2015);??
  100. ??????????
  101. ????????//?print?the?object??
  102. ????????sBeanString ?=?(String)?oToStringMethod.invoke(oCustomizedObject);??
  103. ????????System.out??
  104. ????????????????.println("the?string?of?the?object?created?by?customized?constructor:?"??
  105. ????????????????????????+?sBeanString);??
  106. ????}??
  107. }??
注:?转载请注明出处: http://hejiangtao.iteye.com ,?用于商业得给我分成大笑
发表评论
用户名: 匿名