博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java技术——Java反射机制分析
阅读量:5124 次
发布时间:2019-06-13

本文共 6191 字,大约阅读时间需要 20 分钟。

1. Java的反射机制

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

 

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

 

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

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

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

(这一条在下面没有展示实例,但在之前写过的一篇中有所介绍,有兴趣的可以参考查看。)

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

class S {   }    public class IsInstance {      public static void main(String args[]) {         try {              Class cls = Class.forName("S");  //创建了一个S类的Class对象           boolean b1 = cls.isInstance(new Integer(37));              System.out.println(b1);   //fasle           boolean b2 = cls.isInstance(new S());              System.out.println(b2);   //true      }         catch (Throwable e) {              System.err.println(e);         }      }   }

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

/**  * 获取反射类的所有属性字段  *   * @param ownerClass 反射的类  * @return  * @throws Exception  */  public Field[] getProperty(Class ownerClass) throws Exception {        //获取该类所有属性字段      //Field[] fields = ownerClass.getFields();//只获取public访问权限的属性字段(包括父类的)      Field[] fields = ownerClass.getDeclaredFields();//只获取该类的所有访问权限的属性(不含父类)            //输出所有属性字段      for(int i=0;i

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

/**  * 获取反射类的某个public属性值  *   * @param ownerClass 反射的类  * @param fieldName 属性名  * @return  * @throws Exception  */  public Object getProperty(Object owner,String fieldName) throws Exception {            //得到对象所属类      Class ownerClass = owner.getClass();        //获取该类的某个属性      Field field = ownerClass.getField(fieldName);            //获取某个对象的特定属性      Object property = field.get(owner);            //输出该属性信息      System.out.println(fieldName+"的属性值:"+property.toString());        return property;    }

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

/**  * 获取反射类的该中的所有方法  * @param ownerClass 反射的类  * @return  * @throws Exception  */  public Method[] getMethods(Class ownerClass) throws Exception {        //获取该类所有方法      //Field[] fields = ownerClass.getMethods();//只获取public访问权限的方法(包括父类的)      Method[] methods = ownerClass.getDeclaredMethods();//只获取该类的所有访问权限的方法(不含父类)        //输出所有方法      for(int i=0;i

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

/**  * 执行反射类的该中的某个方法  * @param ownerClass 反射的类  * @param methodName 方法名  * @return  * @throws Exception  */  public Object invokeMethod(Object owner,String methodName,Object[] args) throws Exception {        //得到对象所属类      Class ownerClass = owner.getClass();        //获取该类的某个方法      Method method = ownerClass.getMethod(methodName, null);            //执行某个对象的方法      Object result = method.invoke(owner, args);            //输出结果信息      System.out.println("结果返回值:"+ result);        return result;  }

实例演示方法:

/**  * 测试反射常用方法  */  public void refTest(){      String className = "com.java.reflecttest.Student";        try {                    //通过反射机制,使用类装载器,装载该类          Class
stu = Class.forName(className); Object objStu = stu.newInstance(); //获取反射类的所有属性 System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); System.out.println("调用 getProperty 方法,获取Student类的所有属性"); getProperty(stu); //获取反射类的某个属性值 System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); System.out.println("调用 getProperty 方法,获取Student类的NAME属性值"); getProperty(objStu,"NAME"); //获取反射类的所有方法 System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); System.out.println("调用 getMethods 方法,获取Student类的所有方法"); getMethods(stu); //执行反射类的getInfo方法 System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); System.out.println("调用 invokeMethod 方法,执行Student类的getInfo方法"); invokeMethod(objStu, "getInfo", null); } catch (Exception e) { e.printStackTrace(); } }

演示所用的Student类:

package com.java.reflecttest;    /**  * 学生信息类  *   * @author Longxuan  *  */  public class Student {        /**      * 学号      */      private String stuId ;            /**      * 学号      */      public String STUID;            /**      * 姓名      */      private String name ;            /**      * 姓名      */      public String NAME;        /**      * 年龄      */      private int age;            /**      * 年龄      */      public int AGE;            /**      * 班级      */      private String classid;                      public String getStuId() {          return stuId;      }        public void setStuId(String stuId) {          this.stuId = stuId;      }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public int getAge() {          return age;      }        public void setAge(int age) {          this.age = age;      }        public String getClassid() {          return classid;      }        public void setClassid(String classid) {          this.classid = classid;      }                  /**      * 输出学生信息      */      public void getInfo(){          System.out.println("学生信息:\n学号:"+stuId+"\t姓名:"+name+"\t年龄:"+age+"\t班级:"+classid);      }            /**      * 构造函数      */      public Student(){          init();      }                  /**      * 私有初始化方法      */      private void init(){          this.name = "张三";          this.stuId ="1001";          this.age = 14;          this.classid = "A001";          this.NAME = name;          this.AGE = age;          this.STUID = stuId;      }        }

运行结果:

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

转载于:https://www.cnblogs.com/qitian1/p/6461566.html

你可能感兴趣的文章
12.2日常
查看>>
同步代码时忽略maven项目 target目录
查看>>
Oracle中包的创建
查看>>
团队开发之个人博客八(4月27)
查看>>
发布功能完成
查看>>
【原】小程序常见问题整理
查看>>
C# ITextSharp pdf 自动打印
查看>>
【Java】synchronized与lock的区别
查看>>
django高级应用(分页功能)
查看>>
【转】Linux之printf命令
查看>>
关于PHP会话:session和cookie
查看>>
STM32F10x_RTC秒中断
查看>>
display:none和visiblity:hidden区别
查看>>
C#double转化成字符串 保留小数位数, 不以科学计数法的形式出现。
查看>>
牛的障碍Cow Steeplechase
查看>>
Zookeeper选举算法原理
查看>>
3月29日AM
查看>>
利用IP地址查询接口来查询IP归属地
查看>>
HTML元素定义 ID,Class,Style的优先级
查看>>
构造者模式
查看>>