JAVA反射机制及应用例子

JAVA反射机制是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程式在运行时通过Reflection APIs取得任何一个已知名称的class的内部资讯,包括其modifiers(诸如public, private,static等等)、superclass(例如Object)、interfaces(例如Cloneable),也包括fields和methods的所有资讯,并在运行时调用任意一个对象的方法;生成动态代理。下面以一段代码来看一下主要的Reflection APIs,代码中有相应的注释。

Java代码 收藏代码
  1. importjava.lang.reflect.Array;
  2. importjava.lang.reflect.Constructor;
  3. importjava.lang.reflect.Field;
  4. importjava.lang.reflect.InvocationTargetException;
  5. importjava.lang.reflect.Method;
  6. importjava.lang.reflect.Modifier;
  7. publicclassGoods
  8. {
  9. privateStringid;
  10. privatedoubleprice;
  11. publicGoods(){
  12. System.out.println("itisapen");
  13. }
  14. publicGoods(Strings1,Strings2){
  15. System.out.println(s1+"*"+s2);
  16. }
  17. publicStringgetId()
  18. {
  19. System.out.println(id);
  20. returnid;
  21. }
  22. publicvoidsetId(Stringid)
  23. {
  24. this.id=id;
  25. }
  26. publicStringaddName(Stringstr1,Stringstr2){
  27. returnstr1+str2;
  28. }
  29. /**
  30. *@throwsClassNotFoundException
  31. *@throwsIllegalAccessException
  32. *@throwsInstantiationException
  33. *@throwsNoSuchMethodException
  34. *@throwsSecurityException
  35. *@throwsInvocationTargetException
  36. *@throwsIllegalArgumentException
  37. *@throwsNoSuchFieldException
  38. *@功能描述
  39. *@输入参数
  40. *@反馈值
  41. */
  42. publicstaticvoidmain(String[]args)throwsClassNotFoundException,InstantiationException,IllegalAccessException,SecurityException,NoSuchMethodException,IllegalArgumentException,InvocationTargetException,NoSuchFieldException
  43. {
  44. //TODOAuto-generatedmethodstub
  45. Stringstr="com.xtlh.sinye.Goods";
  46. Classc=Class.forName(str);
  47. Objectobj=c.newInstance();//初始化一个Goods的对象
  48. /**
  49. *//这里设置属性的值调用setId()方法,类型用Class[],参数用Object[]
  50. */
  51. Methodm=c.getMethod("setId",newClass[]{Class.forName("java.lang.String")});
  52. m.invoke(obj,newObject[]{"it'sapple"});
  53. System.out.println("---------------------------------------------------------------------");
  54. /**
  55. *//这里是里获取属性的值调用getId()方法
  56. */
  57. m=c.getMethod("getId",newClass[]{});
  58. m.invoke(obj,newObject[]{});
  59. System.out.println("---------------------------------------------------------------------");
  60. /**
  61. *//获得类中声明的方法
  62. */
  63. Methodme[]=c.getDeclaredMethods();
  64. for(inti=0;i<me.length;i++){
  65. System.out.println("method["+i+"]="+me[i].toString());
  66. }
  67. System.out.println("---------------------------------------------------------------------");
  68. /**
  69. *//模拟instanceof操作符
  70. */
  71. booleanb1=c.isInstance(newInteger(34));
  72. System.out.println("GoodsisainstanceofInteger?"+b1);
  73. booleanb2=c.isInstance(newGoods());//这里调用了无参的构造方法
  74. System.out.println("GoodsisainstanceofGoods?"+b2);
  75. System.out.println("---------------------------------------------------------------------");
  76. /**
  77. *//找出类的方法,类的名称,类的方法的参数,类的方法的返回类型
  78. */
  79. Methodmed[]=c.getDeclaredMethods();
  80. Methodmed1[]=c.getMethods();//从字面意思可以看出来,这里找到所有的方法,即可以找到继承来的方法等
  81. for(inti=0;i<med.length;i++){
  82. Methodmee=med[i];
  83. System.out.println("method#"+i+"name="+mee.getName());
  84. System.out.println("declaringclass="+mee.getDeclaringClass());
  85. //方法的参数类型
  86. Classpvec[]=m.getParameterTypes();
  87. for(intj=0;j<pvec.length;j++){
  88. System.out.println("parameter#"+j+"="+pvec[j]);
  89. }
  90. //方法的异常
  91. Classevec[]=m.getExceptionTypes();
  92. for(intj=0;j<evec.length;j++){
  93. System.out.println("exception#"+j+""+evec[j]);
  94. }
  95. //方法的返回类型
  96. System.out.println("returntype="+mee.getReturnType());
  97. }
  98. System.out.println("---------------------------------------------------------------------");
  99. /**
  100. *//获取类的构造函数
  101. */
  102. Constructorctorlist[]=c.getDeclaredConstructors();
  103. for(inti=0;i<ctorlist.length;i++){
  104. Constructorcons=ctorlist[i];
  105. System.out.println("Constructor#"+i+"name="+cons.getName());
  106. Class[]consParaType=cons.getParameterTypes();//获得构造函数的参数类型
  107. if(consParaType.length==0){
  108. System.out.println("Constructorhavenoparameters");
  109. }else{
  110. for(intj=0;j<consParaType.length;j++){
  111. System.out.println("ConstructorParametertype#"+j+"name="+consParaType[j]);
  112. }
  113. }
  114. }
  115. System.out.println("---------------------------------------------------------------------");
  116. /**
  117. *//获取类的属性
  118. */
  119. Fieldfieldlist[]=c.getDeclaredFields();
  120. for(inti=0;i<fieldlist.length;i++){
  121. Fieldfield=fieldlist[i];
  122. System.out.println("Filed#"+i+"name="+field.getName());//属性名称
  123. System.out.println("Filed#"+i+"type="+field.getType());//属性类型
  124. intmod=field.getModifiers();
  125. System.out.println("modifiers="+Modifier.toString(mod));//属性的修饰符private/public/protected
  126. }
  127. System.out.println("---------------------------------------------------------------------");
  128. /**
  129. *//根据方法的名称来执行方法
  130. */
  131. Classcls=Class.forName("com.xtlh.sinye.Goods");
  132. Classpartypes[]=newClass[2];
  133. partypes[0]=String.class;//更多类型Long.TYPEInteger.TYPE,或者使用Long.class、Integer.class
  134. partypes[1]=Class.forName("java.lang.String");
  135. Methodmeth=cls.getMethod("addName",partypes);
  136. Goodsgoods=newGoods();
  137. Objectarglist[]=newObject[2];
  138. arglist[0]=newString("love");
  139. arglist[1]=newString("grape");
  140. Objectretobj=meth.invoke(goods,arglist);
  141. Stringretval=(String)retobj;
  142. System.out.println(retval);
  143. System.out.println("---------------------------------------------------------------------");
  144. /**
  145. *创建对象,根据指定的参数类型找到相应的构造函数并执行它,以创建一个新的对象实例。使用这种方法可以在程序运行时动态地创建对象,而不是在编译的时候创建对象,这一点非常有价值
  146. */
  147. Classclss=Class.forName("com.xtlh.sinye.Goods");
  148. Classpartypess[]=newClass[2];
  149. partypess[0]=String.class;
  150. partypess[1]=String.class;
  151. Constructorct=clss.getConstructor(partypess);
  152. Objectarglists[]=newObject[2];
  153. arglists[0]=newString("hello");
  154. arglists[1]=newString("orange");
  155. Objectretobjs=ct.newInstance(arglists);
  156. System.out.println("---------------------------------------------------------------------");
  157. /**
  158. *//改变属性的值
  159. */
  160. Classccc=Class.forName("com.xtlh.sinye.Goods");
  161. Fieldfld=ccc.getDeclaredField("price");
  162. Goodsgoods1=newGoods();
  163. System.out.println("price="+goods1.price);
  164. fld.setDouble(goods1,25.0);
  165. System.out.println("price="+goods1.price);
  166. System.out.println("---------------------------------------------------------------------");
  167. /**
  168. *//简单使用数组,创建了10个单位长度的String数组,为第5个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来
  169. */
  170. Classcla=Class.forName("java.lang.String");
  171. Objectarr=Array.newInstance(cla,10);
  172. Array.set(arr,5,"helloWatermelon");
  173. Strings=(String)Array.get(arr,5);
  174. System.out.println(s);
  175. System.out.println("---------------------------------------------------------------------");
  176. /**
  177. *//复杂数组使用,例中创建了一个5x10x15的整型数组,并为处于[3][5][10]的元素赋了值为37。注意,多维数组实际上就是数组的数组,例如,第一个Array.get之后,arrobj是一个10x15的数组。进而取得其中的一个元素,即长度为15的数组,并使用Array.setInt为它的第10个元素赋值。
  178. 注意创建数组时的类型是动态的,在编译时并不知道其类型。
  179. */
  180. intdims[]=newint[]{5,10,15};
  181. Objectarray=Array.newInstance(Integer.TYPE,dims);
  182. Objectarrobj=Array.get(array,3);
  183. Classcl=arrobj.getClass().getComponentType();
  184. System.out.println(cl);
  185. arrobj=Array.get(arrobj,5);
  186. Array.setInt(arrobj,10,37);
  187. intarrcast[][][]=(int[][][])array;
  188. System.out.println(arrcast[3][5][10]);
  189. }
  190. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值