zoukankan      html  css  js  c++  java
  • Java反射机制

    一、什么是反射机制

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

      Java反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

      关于动态代理大家可以参考 http://www.cnblogs.com/yfyzy/p/4401833.html

    二、反射机制和传统的RTTI区别

      RTTI和反射之间的真正区别在于,对RTTI来说,编译器在编译时打开和检查.class文件。(换句话,我们可以用“普通”方式调用对象的所有方法。)而对于反射机制来说,.class文件在编译时是不可以获取的,所以在运行时打开和检查.class文件。

    三、反射机制实现

      反射机制基于Java的类型信息实现,关于Java类型信息可以参考 http://www.cnblogs.com/yfyzy/p/4398448.html 

      Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method。

      1).Class ——类对象

      2).Constructor——类的构造器对象

      3).Field——类的属性对象

      4).Method——类的方法对象。

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

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

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

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

      4).在运行时调用任意一个对象的方法和访问任意一个对象的属性。

    五 、反射机制中常用的一些方法

      1、得到构造器的方法 

        1)Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, 

        2)Constructor[] getConstructors() -- 获得类的所有公共构造函数 

        3)Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别    无关) 

        4)Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 

      2、获得字段信息的方法 

        1)Field getField(String name) -- 获得命名的公共字段 

        2)Field[] getFields() -- 获得类的所有公共字段 

        3)Field getDeclaredField(String name) -- 获得类所有声明的命名的字段 

        4)Field[] getDeclaredFields() -- 获得类声明的所有字段 

      3、获得方法信息的方法 

        1)Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法 

        2)Method[] getMethods() -- 获得类的所有公共方法 

        3)Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名    的方法 

        4)Method[] getDeclaredMethods() -- 获得类声明的所有方法 

    六、总结+实践

      在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。使用反射就可以变成“实例化对象——getClass()方法——得到完整的‘包.类’名称”这样的过程。正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。

       下面是一个通过反射机制调用类的例子。该例子是小弟在一个前辈的基础上的一点点小改动,感觉这位前辈写的挺好的。这个是那位前辈的博客URL: http://blog.csdn.net/nieweilin/article/details/5908165

      1 import java.lang.reflect.Array;     
      2 import java.lang.reflect.Constructor;     
      3 import java.lang.reflect.Field;     
      4 import java.lang.reflect.Method;     
      5     
      6     
      7 /**   
      8  * Java Reflection Cookbook   
      9  *   
     10  * @author Michael Lee   
     11  * @since 2015-4-09   
     12  * @version 0.2a   
     13  */    
     14     
     15 public class Reflection {     
     16     /**   
     17      * 得到某个对象的属性   
     18      *   
     19      * @param owner, fieldName   
     20      * @return 该属性对象   
     21      * @throws Exception   
     22      *   
     23      */   
     24     
     25     public Object getProperty(Object owner, String fieldName) throws Exception {     
     26         Class ownerClass = owner.getClass();     
     27     
     28         //该写法只能获取该对象的所有公有的属性
     29         //Field field = ownerClass.getField(fieldName); 
     30         
     31         //该写法可以获取对对象的所有属性
     32         Field field = ownerClass.getDeclaredField(fieldName);
     33         
     34         //设置访问权限控制,当为true时,私有属性也可以访问
     35         field.setAccessible(true);    
     36   
     37         return field.get(owner);     
     38     }  
     39     
     40     
     41     /**   
     42      * 得到某类的静态公共属性   
     43      *   
     44      * @param className   类名   
     45      * @param fieldName   属性名   
     46      * @return 该属性对象   
     47      * @throws Exception   
     48      */    
     49     public Object getStaticProperty(String className, String fieldName)     
     50             throws Exception {     
     51         Class ownerClass = Class.forName(className);     
     52     
     53         //该写法只能获取该对象的所有公有的属性
     54         //Field field = ownerClass.getField(fieldName); 
     55         
     56         //该写法可以获取对对象的所有属性
     57         Field field = ownerClass.getDeclaredField(fieldName);
     58         
     59         //设置访问权限控制,当为true时,私有属性也可以访问
     60         field.setAccessible(true);    
     61   
     62         return field.get(ownerClass);    
     63     }     
     64     
     65     
     66     /**   
     67      * 执行某对象方法   
     68      *   
     69      * @param owner   
     70      *            对象   
     71      * @param methodName   
     72      *            方法名   
     73      * @param args   
     74      *            参数   
     75      * @return 方法返回值   
     76      * @throws Exception   
     77      */    
     78     public Object invokeMethod(Object owner, String methodName, Object[] args)     
     79             throws Exception {     
     80     
     81         Class ownerClass = owner.getClass();     
     82     
     83         Class[] argsClass = new Class[args.length];     
     84     
     85         for (int i = 0, j = args.length; i < j; i++) {     
     86             argsClass[i] = args[i].getClass();     
     87         }     
     88     
     89         //该写法只能调用该对象的公有方法
     90        // Method method = ownerClass.getMethod(methodName, argsClass); 
     91         
     92         //该写法可以调用该对象的所有方法
     93         Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
     94     
     95         //设置访问权限控制,当为true时,私有方法也可以访问
     96         method.setAccessible(true);
     97         
     98         return method.invoke(owner, args);     
     99     }     
    100     
    101     
    102       /**   
    103      * 执行某类的静态方法   
    104      *   
    105      * @param className   
    106      *            类名   
    107      * @param methodName   
    108      *            方法名   
    109      * @param args   
    110      *            参数数组   
    111      * @return 执行方法返回的结果   
    112      * @throws Exception   
    113      */    
    114     public Object invokeStaticMethod(String className, String methodName,     
    115             Object[] args) throws Exception {     
    116         Class ownerClass = Class.forName(className);     
    117     
    118         Class[] argsClass = new Class[args.length];     
    119     
    120         for (int i = 0, j = args.length; i < j; i++) {     
    121             argsClass[i] = args[i].getClass();     
    122         }     
    123     
    124          //该写法只能调用该类的静态公有方法
    125         // Method method = ownerClass.getMethod(methodName, argsClass);     
    126     
    127         //该写法可以调用该类的所有静态方法
    128         Method method = ownerClass.getDeclaredMethod(methodName, argsClass);
    129         
    130         //设置访问权限控制,当为true时,私有方法也可以访问
    131         method.setAccessible(true);
    132         
    133         return method.invoke(null, args);     
    134     }     
    135     
    136     
    137     
    138     /**   
    139      * 新建实例   
    140      *   
    141      * @param className   
    142      *            类名   
    143      * @param args   
    144      *            构造函数的参数   
    145      * @return 新建的实例   
    146      * @throws Exception   
    147      */    
    148     public Object newInstance(String className, Object[] args) throws Exception {     
    149         Class newoneClass = Class.forName(className);     
    150     
    151         Class[] argsClass = new Class[args.length];     
    152     
    153         for (int i = 0, j = args.length; i < j; i++) {     
    154             argsClass[i] = args[i].getClass();     
    155         }     
    156     
    157        //该写法只能获取该类的公有构造函数
    158         //Constructor cons = newoneClass.getConstructor(argsClass);     
    159     
    160         //该写法可以获取该类的所有构造函数
    161         Constructor cons = newoneClass.getDeclaredConstructor(argsClass); 
    162         
    163         //设置访问权限控制,当为true时,私有方法也可以访问
    164         cons.setAccessible(true);
    165         
    166         return cons.newInstance(args);     
    167     
    168     }     
    169     
    170     
    171          
    172     /**   
    173      * 是不是某个类的实例   
    174      * @param obj 实例   
    175      * @param cls 类   
    176      * @return 如果 obj 是此类的实例,则返回 true   
    177      */    
    178     public boolean isInstance(Object obj, Class cls) {     
    179         return cls.isInstance(obj);     
    180     }     
    181          
    182     /**   
    183      * 得到数组中的某个元素   
    184      * @param array 数组   
    185      * @param index 索引   
    186      * @return 返回指定数组对象中索引组件的值   
    187      */    
    188     public Object getByArray(Object array, int index) {     
    189         return Array.get(array,index);     
    190     }     
    191 }    
  • 相关阅读:
    spring学习(十七)--annotion注解
    spring学习(十六)--spring方式实现工程初始化配置
    spring学习(十五)--自己实现BeanFactory
    JDBC使用SPI机制解析
    SPI机制
    spring学习(十三)--自己实现SpringServletContainerInitializer
    cetnos基本操作
    CentOS基本命令
    面向对象的双下方法
    Flask数据连接池 DBUtils
  • 原文地址:https://www.cnblogs.com/yfyzy/p/4404080.html
Copyright © 2011-2022 走看看