`
sameseam
  • 浏览: 23169 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

也浅谈下Java反射

 
阅读更多
Java代码 复制代码
  1. importjava.lang.reflect.Array;
  2. importjava.lang.reflect.Constructor;
  3. importjava.lang.reflect.Field;
  4. importjava.lang.reflect.Method;
  5. importjava.util.Arrays;
  6. /**
  7. *浅谈Java反射
  8. *
  9. *@authorleejon
  10. *
  11. */
  12. publicclassReflectTest{
  13. @SuppressWarnings("unchecked")
  14. publicstaticvoidmain(String[]args)throwsException{
  15. /**
  16. *反射的概念:反射就是把Java类中的各种成分映射成相应的Java类。
  17. *例如:一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等信息
  18. *也用一个个的Java类来表示。就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。
  19. *表示Java类的Class类显然要提供一系列的方法来获取其中的变量,方法,构造方法,修饰符,包等信息。这些信息用相应类的实例对象来表示。
  20. *他们就是Field,Method,Constructor,Package等。
  21. *一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象。
  22. */
  23. System.out.println("==========Class类Demo========");
  24. Class<?extendsObject>cla1=String.class;
  25. Class<?extendsObject>cla2=Class.forName("java.lang.String");
  26. /**
  27. *之所以相等。是因为在jvm中已经装载了String类对象的字节码
  28. */
  29. System.out.println("两对象是否相等:"+(cla1==cla2));
  30. /**
  31. *String类不属于原始类型
  32. */
  33. System.out.println("是否是原始类型:"+cla1.isPrimitive());
  34. System.out.println("int是否是原始类型?:"+int.class.isPrimitive());
  35. System.out.println("原始类型及其包装类型字节码:"+(Integer.class==int.class));
  36. /**
  37. *基本类型的字节码==其包装类的TYPE属性的字节码
  38. */
  39. System.out.println(int.class==Integer.TYPE);
  40. /**
  41. *数组不属于原始类型,是为另外一种类型:Array
  42. */
  43. System.out.println("原始类型的数组的字节码不是原始类型:"+(int[].class.isPrimitive()));
  44. System.out.println("数组是否为Array类型:"+int[].class.isArray());
  45. System.out.println("=====================反射中构造方法demo=================");
  46. /**
  47. *获取某个类的所有的构造函数,返回一个Constructor类型的数组
  48. */
  49. Constructor[]constructors=StringBuffer.class.getConstructors();
  50. for(Constructorconstructor:constructors){
  51. System.out.println(constructor.getName());
  52. }
  53. /**
  54. *根据参数的类型获取某个类的构造函数
  55. */
  56. Constructorconstructor=String.class
  57. .getConstructor(StringBuffer.class);
  58. System.out.println(constructor.getName());
  59. /**
  60. *注意:创建对象的时候指定的参数类型要和获取该Constructor对象时的类型相同
  61. *如果类型不同,在IDE中可以通过编译,但是运行期则会抛出异常,----类型不匹配
  62. *假设:constructor.newInstance(newStringBuffer("demo"));
  63. *则运行异常,因为String.class.getConstructor(StringBuffer.class)
  64. *获取Constructor实例时指定的参数类型为StringBuffer
  65. *=============================================================
  66. *××××××要注意的地方:××××××××调用获得的方法时要用相同的类型×××××××××××××
  67. *=============================================================
  68. *
  69. *Class类的newInstance和Constructor对象的newInstance的关系:
  70. *Class类的newInstance方法为创建类的对象提供便利。
  71. *一般情况下,创建对的对象步骤:class-->Constructor-->newIntance(Class<?>...paramType)
  72. *Class.newInstance():该方法内部先得到默认的构造方法,然后用该构造方法创建实例。/
  73. *内部代码用到了缓存机制来保存默认构造方法的实例对象
  74. */
  75. Stringstr=(String)constructor.newInstance(newStringBuffer("demo"));
  76. System.out.println("根据Constructor的newInstance方法所创建的实例:"+str);
  77. System.out.println("str的第二个字符:"+str.charAt(1));
  78. System.out.println("=============成员变量的反射============");
  79. ReflectPointpp1=newReflectPoint(3,5);
  80. FieldfieldY=pp1.getClass().getField("y");
  81. /**
  82. *fieldY不表示某个对象代表的值,而单纯表示对象本身
  83. */
  84. System.out.println("FieldY:"+fieldY);
  85. /**
  86. *如果要获取fieldY在具体对象上的值(字段的值)则:fieldY.get(OneObj)
  87. */
  88. System.out.println("fieldY的值:"+fieldY.get(pp1));
  89. /**
  90. *对于私有的成员变量,不能使用getField获得,所以,以下代码运行时出错
  91. */
  92. //FieldfieldX=pp1.getClass().getField("x");
  93. //System.out.println("FieldX:"+fieldX);
  94. //System.out.println("fieldX的值:"+fieldX.get(pp1));
  95. /**
  96. *对于私有的成员属性,可以采用getDeclaredField("属性名")的方式获取该成员(Filed)的引用
  97. *并且要设置其为可访问:如:fieldX.setAccessible(true);该访问成员的方式可称之为暴力反射^_^
  98. *========================================================
  99. *对于这里的fieldX和上面的fieldY,仅仅代表字节码的对象,而不是表示某个对象中的一个成员属性的值
  100. *如果要将其和某个对象相关联起来,则可以使用:fieldX.get(pp1),表示在pp1这个对象中x这个属性的值
  101. *========================================================
  102. */
  103. FieldfieldX=pp1.getClass().getDeclaredField("x");
  104. fieldX.setAccessible(true);
  105. System.out.println("FieldX:"+fieldX);
  106. System.out.println("fieldX的值:"+fieldX.get(pp1));
  107. System.out.println("===========Medthod类===============");
  108. MethodmethodCharAt=String.class.getMethod("charAt",int.class);
  109. System.out.println(methodCharAt);
  110. /**
  111. *以反射的方式调用某个对象的方法用:invoke(要调用那个对象,参数数组):后面的参数方法原型为可变长度参数,其内部以数组形式实现。
  112. */
  113. StringmethodStr="HelloWorld!";
  114. System.out.println(methodCharAt.invoke(methodStr,1));
  115. System.out.println("============数组的反射==============");
  116. int[]arr1=newint[]{45,5,6,666,778};
  117. System.out.println(arr1.getClass().getSuperclass());
  118. int[]arr11=newint[]{1,2,3};
  119. /**
  120. *这里比较的是两个对象,所以不相等。而下面的getClass则比较的是字节码。因为两个数组都是int型的,所以,他们的字节码是相等的。
  121. */
  122. System.out.println("arr1==arr11:"+(arr1==arr11));
  123. System.out.println("arr1.getClass()==arr11.getClass():"
  124. +(arr1.getClass()==arr11.getClass()));
  125. int[][]arr2=newint[][]{newint[]{1,2,3,4,5},
  126. newint[]{6,7,8,9,10}};
  127. System.out.println("arr2:"+arr2);
  128. String[]arr3=newString[]{"hello","world"};
  129. System.out.println("arr3:"+arr3);
  130. /**
  131. *基本类型的一维数组只可以被当作Object使用而不能被当作Object[]来使用。
  132. *非基本类型的一维数组,既可以作为Oject类型来使用,也可以作为Object[]类型来使用
  133. */
  134. System.out.println(arr2.getClass().getSuperclass());
  135. System.out.println("StringsuperClass:"
  136. +arr3.getClass().getSuperclass().getName());
  137. //Object[]obj1=arr1;(编译器报错)
  138. Object[]obj2=arr2;
  139. Object[]obj3=arr3;
  140. /**
  141. *以下两行显示[[I@14318bb<br>
  142. *[Ljava.lang.String;@ca0b6
  143. */
  144. System.out.println(obj2);
  145. System.out.println(obj3);
  146. System.out.println("=============java.util.Arrays类==========");
  147. /**
  148. *对于字符串类型的数组。用Arrays的静态方法asList(Object...a)能够将obj2作为一个List集合将其值输出,
  149. *但是,对于int类型的数组,虽然转换成为了List,却还是输出其每个元素的地址,这是为什么呢?
  150. *因为arr1数组是int型,属于基本类型。arr1
  151. *.getClass().getName()=[I,所以JDK编译器将整个数组作为一个Object(一个整型数组)进行处理.
  152. *这也是Arrays.asList(Object...a)处理int[]和String[]时的差异
  153. */
  154. System.out.println(Arrays.asList(arr1));
  155. System.out.println(arr1.getClass().getName());
  156. System.out.println(Arrays.asList(obj3));
  157. /**对数组进行反射操作*/
  158. ObjectprintObj=arr3;
  159. Classclazz=printObj.getClass();
  160. if(clazz.isArray()){
  161. /**如果是数组*/
  162. /**得到长度*/
  163. System.out.println("传入的参数是数组");
  164. intlength=Array.getLength(printObj);
  165. for(inti=0;i<length;i++){
  166. System.out.println(Array.get(printObj,i));
  167. }
  168. }else{
  169. System.out.println("传入的参数不是数组");
  170. System.out.println(printObj);
  171. }
  172. }
  173. }


Java代码 复制代码
  1. publicclassReflectPoint{
  2. privateintx;
  3. publicinty;
  4. publicReflectPoint(intx,inty){
  5. this.x=x;
  6. this.y=y;
  7. System.out.println("X:"+this.x+",Y:"+this.y);
  8. }
  9. @Override
  10. publicStringtoString(){
  11. return"X:"+this.x+",Y:"+this.y;
  12. }
  13. }
分享到:
评论

相关推荐

    Java反射技术浅谈.pdf

    Java反射技术浅谈 Java反射技术是一种强大的技术,它允许Java程序访问、检测和修改它自己的状态或行为。通过反射,Java程序可以加载一个运行时才知道名称的类,获取其完整的内部信息,并创建其对象,或者对其属性...

    Java反射技术浅谈 (1).pdf

    Java反射技术浅谈 Java反射技术是一种可以访问、检测和修改程序本身状态或行为的能力。通过反射,Java程序可以加载一个运行时才知道名称的类,得到其完整内部信息,并创建其对象,或对其属性设值,或调用其方法。...

    浅谈Java程序设计在线开放课程.zip

    "浅谈Java程序设计在线开放课程"这个主题,将深入探讨Java语言的核心概念、编程实践以及如何通过在线平台有效地学习这门技术。 Java以其“一次编写,到处运行”的跨平台特性,成为了企业级应用开发的首选语言。课程...

    浅谈java代理机制 .txt

    ### 浅谈Java代理机制 #### 一、引言 在深入探讨Java代理机制之前,我们首先需要了解代理模式的基本概念及其应用场景。代理模式是一种结构型设计模式,它为其他对象提供了一种代理以控制对这个对象的访问。在Java...

    浅谈Java模型以外的类型策略

    在Java中,虽然其类型系统相对固定,但可以通过一些技术来扩展其灵活性,例如使用泛型、反射和动态代理等。泛型提供了一种在编译时处理类型的方式,而反射允许在运行时检查和操作类的结构,动态代理则能实现接口的...

    java之浅谈深说--教你如何成长

    ### Java之浅谈深说——教你如何成长为Java编程高手 在IT行业中,Java作为一种广泛使用的编程语言,其重要性不言而喻。对于希望成为Java编程高手的学习者来说,掌握正确的学习路径至关重要。本文将根据提供的标题、...

    浅谈MyBatis通用Mapper实现原理

    浅谈MyBatis通用Mapper实现原理 MyBatis通用Mapper是MyBatis框架中的一种通用Mapper实现方式,主要提供了一些通用的方法,这些方法是以接口的形式提供的。通用Mapper的实现原理主要是通过Java反射机制和MyBatis框架...

    浅谈使用java实现阿里云消息队列简单封装

    浅谈使用java实现阿里云消息队列简单封装 本文主要介绍了使用Java实现阿里云消息队列的简单封装,包括对阿里云消息队列的介绍、设计方案、消息发送和接收的实现等。 一、阿里云消息队列简介 阿里云提供了两种消息...

    浅谈用java实现事件驱动机制

    除了观察者模式,还可以利用Java的反射能力来实现事件驱动。反射允许我们在运行时动态地获取类的信息并调用方法。以下是如何使用反射实现事件驱动: 1. 创建一个事件处理器类,包含事件源对象和事件处理函数的名称...

    浅谈Java中对类的主动引用和被动引用

    浅谈Java中对类的主动引用和被动引用 Java 中的类引用可以分为两种:主动引用和被动引用。理解这两种引用机制对于 Java 程序的正确执行和优化至关重要。 一、主动引用 主动引用是指在 Java 程序中明确地使用某个...

    浅谈Java中的class类

    在Java编程语言中,`Class`类扮演着至关重要的角色,它是Java反射机制的基础。`Class`类代表了运行时的类信息,允许我们在程序运行时动态地获取类的结构和属性,包括类的成员变量、方法、构造器等。这使得Java具备了...

    浅谈java Properties类的使用基础

    * 多线程环境下的配置共享:多个线程可以共享单个Properties对象,而无需进行外部同步。 * 配置信息持久化:Properties类可以将配置信息持久化到.properties文件中,以便下次使用。 Java Properties类是Java标准库...

    java基础PPT

    11. **JNI与JVM原理**:浅谈Java Native Interface(JNI),用于在Java程序中调用本地(非Java)代码,以及JVM的工作原理,包括类加载、内存管理和垃圾收集。 12. **案例分析**:可能包含一些简单的编程实例,帮助...

    java程序员初学20道题

    浅谈JDBC的概念理解与学习 JDBC(Java Database Connectivity)是Java中用来对数据库进行统一访问、管理的一种机制。通过JDBC,开发人员可以使用标准Java API来连接不同的数据库管理系统。 - **JDBC驱动模型**:...

    浅谈计算机应用软件开发中编程语言的选择研究中英文对照.pdf

    浅谈计算机应用软件开发中编程语言的选择研究 随着信息技术的飞速发展,计算机应用软件已经深入到我们生活的各个领域,从个人娱乐、办公自动化到工业自动化、云计算等,无处不在。软件开发企业面临着激烈的市场竞争...

    浅谈Java编程中的内存泄露情况

    此外,Java虚拟机(JVM)的内存区域也会影响内存泄露的发生。例如,堆内存溢出(OutOfMemoryError: Java heap space)通常是由于对象实例或数组创建过多,导致年轻代和年老代空间不足。方法区内存溢出...

    java中Class.forName的作用浅谈

    在Java编程语言中,`Class.forName()`方法是一个非常重要的...同时,`newInstance()`则是通过反射来创建对象的方法,它在某些设计模式和场景下具有独特的价值。了解和掌握这些概念对于深入理解Java的运行机制至关重要。

Global site tag (gtag.js) - Google Analytics