1. Java的反射机制

动态语言是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言。但Java它却有着一个非常突出的动态相关机制:反射。

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Java反射机制主要提供了以下功能:

(1)在运行时判断任意一个对象所属的类;

(2)在运行时构造任意一个类的对象;

(这一条在下面没有展示实例,但在之前写过的一篇Java中创建对象的5种方式中有所介绍,有兴趣的可以参考查看。)

(3)在运行时判断任意一个类所具有的成员变量和方法;

(4)在运行时调用任意一个对象的方法;

(5)生成动态代理。

2. Java反射API

反射API用来生成在当前Java虚拟机中的类、接口或者对象的信息。

Class类:反射的核心类,可以获取类的属性,方法等内容信息。

Field类:Java.lang.reflect.表示类的属性,可以获取和设置类的中属性值。

Method类:Java.lang.reflect。表示类的方法,它可以用来获取类中方法的信息或者执行方法

Construcor类:Java.lang.reflect。表示类的构造方法。

 

3.反射常见用法

3.1 判断对象是否属于反射得到的类(isInstance)

  1. class S {
  2. }
  3. public class IsInstance {
  4. public static void main(String args[]) {
  5. try {
  6. Class cls = Class.forName("S"); //创建了一个S类的Class对象
  7. boolean b1 = cls.isInstance(new Integer(37));
  8. System.out.println(b1); //fasle
  9. boolean b2 = cls.isInstance(new S());
  10. System.out.println(b2); //true
  11. }
  12. catch (Throwable e) {
  13. System.err.println(e);
  14. }
  15. }
  16. }


3.2 获取某个反射类的所有属性字段

  1. /**
  2. * 获取反射类的所有属性字段
  3. *
  4. * @param ownerClass 反射的类
  5. * @return
  6. * @throws Exception
  7. */
  8. public Field[] getProperty(Class ownerClass) throws Exception {
  9.  
  10. //获取该类所有属性字段
  11. //Field[] fields = ownerClass.getFields();//只获取public访问权限的属性字段(包括父类的)
  12. Field[] fields = ownerClass.getDeclaredFields();//只获取该类的所有访问权限的属性(不含父类)
  13.  
  14. //输出所有属性字段
  15. for(int i=0;i<fields.length;i++){
  16. System.out.println("属性:"+fields[i]);
  17. }
  18.  
  19. return fields;
  20. }

3.3 获取反射类的某个public属性值

  1. /**
  2. * 获取反射类的某个public属性值
  3. *
  4. * @param ownerClass 反射的类
  5. * @param fieldName 属性名
  6. * @return
  7. * @throws Exception
  8. */
  9. public Object getProperty(Object owner,String fieldName) throws Exception {
  10.  
  11. //得到对象所属类
  12. Class ownerClass = owner.getClass();
  13.  
  14. //获取该类的某个属性
  15. Field field = ownerClass.getField(fieldName);
  16.  
  17. //获取某个对象的特定属性
  18. Object property = field.get(owner);
  19.  
  20. //输出该属性信息
  21. System.out.println(fieldName+"的属性值:"+property.toString());
  22.  
  23. return property;
  24.  
  25. }


3.4 获取反射类的该中的所有方法

  1. /**
  2. * 获取反射类的该中的所有方法
  3. * @param ownerClass 反射的类
  4. * @return
  5. * @throws Exception
  6. */
  7. public Method[] getMethods(Class ownerClass) throws Exception {
  8.  
  9. //获取该类所有方法
  10. //Field[] fields = ownerClass.getMethods();//只获取public访问权限的方法(包括父类的)
  11. Method[] methods = ownerClass.getDeclaredMethods();//只获取该类的所有访问权限的方法(不含父类)
  12.  
  13. //输出所有方法
  14. for(int i=0;i<methods.length;i++){
  15. System.out.println("方法:" +methods[i]);
  16. }
  17.  
  18. return methods;
  19. }


3.5 执行反射类的该中的某个方法

  1. /**
  2. * 执行反射类的该中的某个方法
  3. * @param ownerClass 反射的类
  4. * @param methodName 方法名
  5. * @return
  6. * @throws Exception
  7. */
  8. public Object invokeMethod(Object owner,String methodName,Object[] args) throws Exception {
  9.  
  10. //得到对象所属类
  11. Class ownerClass = owner.getClass();
  12.  
  13. //获取该类的某个方法
  14. Method method = ownerClass.getMethod(methodName, null);
  15.  
  16. //执行某个对象的方法
  17. Object result = method.invoke(owner, args);
  18.  
  19. //输出结果信息
  20. System.out.println("结果返回值:"+ result);
  21.  
  22. return result;
  23. }


实例演示方法:

  1. /**
  2. * 测试反射常用方法
  3. */
  4. public void refTest(){
  5. String className = "com.java.reflecttest.Student";
  6.  
  7. try {
  8.  
  9. //通过反射机制,使用类装载器,装载该类
  10. Class<?> stu = Class.forName(className);
  11. Object objStu = stu.newInstance();
  12.  
  13. //获取反射类的所有属性
  14. System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  15. System.out.println("调用 getProperty 方法,获取Student类的所有属性");
  16. getProperty(stu);
  17.  
  18. //获取反射类的某个属性值
  19. System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  20. System.out.println("调用 getProperty 方法,获取Student类的NAME属性值");
  21. getProperty(objStu,"NAME");
  22.  
  23. //获取反射类的所有方法
  24. System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  25. System.out.println("调用 getMethods 方法,获取Student类的所有方法");
  26. getMethods(stu);
  27.  
  28. //执行反射类的getInfo方法
  29. System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
  30. System.out.println("调用 invokeMethod 方法,执行Student类的getInfo方法");
  31. invokeMethod(objStu, "getInfo", null);
  32.  
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }

演示所用的Student类:

  1. package com.java.reflecttest;
  2.  
  3. /**
  4. * 学生信息类
  5. *
  6. * @author Longxuan
  7. *
  8. */
  9. public class Student {
  10.  
  11. /**
  12. * 学号
  13. */
  14. private String stuId ;
  15.  
  16. /**
  17. * 学号
  18. */
  19. public String STUID;
  20.  
  21. /**
  22. * 姓名
  23. */
  24. private String name ;
  25.  
  26. /**
  27. * 姓名
  28. */
  29. public String NAME;
  30.  
  31. /**
  32. * 年龄
  33. */
  34. private int age;
  35.  
  36. /**
  37. * 年龄
  38. */
  39. public int AGE;
  40.  
  41. /**
  42. * 班级
  43. */
  44. private String classid;
  45.  
  46. public String getStuId() {
  47. return stuId;
  48. }
  49.  
  50. public void setStuId(String stuId) {
  51. this.stuId = stuId;
  52. }
  53.  
  54. public String getName() {
  55. return name;
  56. }
  57.  
  58. public void setName(String name) {
  59. this.name = name;
  60. }
  61.  
  62. public int getAge() {
  63. return age;
  64. }
  65.  
  66. public void setAge(int age) {
  67. this.age = age;
  68. }
  69.  
  70. public String getClassid() {
  71. return classid;
  72. }
  73.  
  74. public void setClassid(String classid) {
  75. this.classid = classid;
  76. }
  77.  
  78. /**
  79. * 输出学生信息
  80. */
  81. public void getInfo(){
  82. System.out.println("学生信息:\n学号:"+stuId+"\t姓名:"+name+"\t年龄:"+age+"\t班级:"+classid);
  83. }
  84.  
  85. /**
  86. * 构造函数
  87. */
  88. public Student(){
  89. init();
  90. }
  91.  
  92. /**
  93. * 私有初始化方法
  94. */
  95. private void init(){
  96. this.name = "张三";
  97. this.stuId ="1001";
  98. this.age = 14;
  99. this.classid = "A001";
  100. this.NAME = name;
  101. this.AGE = age;
  102. this.STUID = stuId;
  103. }
  104.  
  105. }


运行结果:

4. 反射的效率

在Stackoverflow上认为反射比较慢的程序员主要有如下看法,如果你面试遇到了,可以这样回答:

(1)验证等防御代码过于繁琐,这一步本来在link阶段,现在却在计算时进行验证。

(2)产生很多临时对象,造成GC与计算时间消耗。

(3)由于缺少上下文,丢失了很多运行时的优化,比如JIT(它可以看作JVM的重要评测标准之一)

当然,我个人的看法是,现代JVM也不是非常慢了,它能够对反射代码进行缓存以及通过方法计数器同样实现JIT优化,所以反射不一定慢。更重要的是,很多情况下,你自己的代码才是限制程序的瓶颈。因此,在开发效率远大于运行效率的的基础上,大胆使用反射,放心开发吧。


文章转自:http://blog.csdn.net/xiaoxian8023/article/details/9206055

http://www.jianshu.com/p/f83556bcae59

Java技术——Java反射机制分析的更多相关文章

  1. Java 类反射机制分析

    Java 类反射机制分析 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.在计算机科学领域,反射是一类应用,它们能够自描述和自控制.这类应用通过某 ...

  2. Java 反射机制分析指南

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  3. Java反射机制分析指南

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  4. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  5. java 中利用反射机制获取和设置实体类的属性值

    摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...

  6. Java中的反射机制和动态代理

    一.反射概述 反射机制指的是Java在运行时候有一种自观的能力,能够了解自身的情况为下一步做准备,其想表达的意思就是:在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法:对于任意一个对象 ...

  7. Java高级特性——反射机制(第二篇)

    在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...

  8. 小白都能学会的Java注解与反射机制

    前言 Java注解和反射是很基础的Java知识了,为何还要讲它呢?因为我在面试应聘者的过程中,发现不少面试者很少使用过注解和反射,甚至有人只能说出@Override这一个注解.我建议大家还是尽量能在开 ...

  9. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

随机推荐

  1. 大都市 meg

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景. 昔日,乡下有依次编号为1.. ...

  2. .net笔试题二(填空题、选择题)

    1.面向对象的语言具有_______性.________性._______性答:封装.继承.多态. 2.能用foreach遍历访问的对象需要实现 ____________接口或声明__________ ...

  3. Java基础:(三)运算

    一.参数传递 Java的参数是以值传递的形式传入方法中,而不是引用传递. 二.隐式类型转换 Java不能隐式执行向下转型,因为这会使精度降低:但是使用 += 运算符可以执行隐式类型转换. float ...

  4. Java中的Serializable接口和transient关键字

    Java中的Serializable接口和transient关键字 Table of Contents 1. 向memcached中放数据时遇到NotSerializableException异常 2 ...

  5. Linux常用操作详解

    第1章 Linux命令基础 1.1 习惯 操作前备份,操作后检查 1.2 简单目录结构 一切从根开始,与windows不同 1.3 规则 [root@znix ~]# [用户名@主机名 你在哪]# 1 ...

  6. GreenDao 3.x 注解中ToOne和ToMany的个人理解

    GreenDao是什么东西这个就不用多说了.自从GreenDao升级到3.0之后,编译的方法发生了改变.当然这个改变是有助于快速开发的. 区别在哪随便百度一下都可以知道.这里就不多说了. 这里主要说的 ...

  7. COGS 1215. [Tyvj Aug11] 冗余电网

    ★   输入文件:ugrid.in   输出文件:ugrid.out   简单对比时间限制:1 s   内存限制:128 MB TYVJ八月月赛提高组第2题 测试点数目:5 测试点分值:20 --内存 ...

  8. 洛谷 P1855 榨取kkksc03

    题目描述 洛谷2的团队功能是其他任何oj和工具难以达到的.借助洛谷强大的服务器资源,任何学校都可以在洛谷上零成本的搭建oj并高效率的完成训练计划. 为什么说是搭建oj呢?为什么高效呢? 因为,你可以上 ...

  9. hdu 5093 Battle ships (二分图)

    二分图最大匹配问题 遇到冰山就把行列拆成两个部分.每个部分x也好,y也好只能匹配一次 图画得比较草,将就着看 横着扫一遍,竖着扫一遍,得到编号 一个位置就对应一个(xi,yi)就是X集到Y集的一条边, ...

  10. lca(最近公共祖先(离线))

    转自大佬博客 : https://www.cnblogs.com/JVxie/p/4854719.html   LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 首先是最近公共祖先 ...