Java反射经典实例 Java Reflection Cookbook (初级)

Java代码 复制代码
  1. Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫——反射。反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。   
  2.   
  3. 1. 得到某个对象的属性   
  4.   
  5. 1 public Object getProperty(Object owner, String fieldName) throws Exception {   
  6. 2     Class ownerClass = owner.getClass();   
  7. 3    
  8. 4     Field field = ownerClass.getField(fieldName);   
  9. 5    
  10. 6     Object property = field.get(owner);   
  11. 7    
  12. 8     return property;   
  13. 9 }   
  14. Class ownerClass = owner.getClass():得到该对象的Class。   
  15.   
  16. Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。   
  17.   
  18. Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。   
  19.   
  20.   
  21.   
  22. 2. 得到某个类的静态属性   
  23.   
  24.  1 public Object getStaticProperty(String className, String fieldName)   
  25.  2             throws Exception {   
  26.  3     Class ownerClass = Class.forName(className);   
  27.  4    
  28.  5     Field field = ownerClass.getField(fieldName);   
  29.  6    
  30.  7     Object property = field.get(ownerClass);   
  31.  8    
  32.  9     return property;   
  33. 10 }   
  34.   
  35. Class ownerClass = Class.forName(className) :首先得到这个类的Class。   
  36.   
  37. Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。   
  38.   
  39. Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。   
  40.   
  41.   
  42. 3. 执行某对象的方法   
  43.   
  44.  1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {   
  45.  2    
  46.  3     Class ownerClass = owner.getClass();   
  47.  4    
  48.  5     Class[] argsClass = new Class[args.length];   
  49.  6    
  50.  7     for (int i = 0, j = args.length; i < j; i++) {   
  51.  8         argsClass[i] = args[i].getClass();   
  52.  9     }   
  53. 10    
  54. 11     Method method = ownerClass.getMethod(methodName, argsClass);   
  55. 12    
  56. 13     return method.invoke(owner, args);   
  57. 14 }   
  58. Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。   
  59.   
  60. 59行:配置参数的Class数组,作为寻找Method的条件。   
  61.   
  62. Method method = ownerClass.getMethod(methodName, argsClass):通过Method名和参数的Class数组得到要执行的Method。   
  63.   
  64. method.invoke(owner, args):执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值。   
  65.   
  66.   
  67. 4. 执行某个类的静态方法   
  68.   
  69.  1 public Object invokeStaticMethod(String className, String methodName,   
  70.  2             Object[] args) throws Exception {   
  71.  3     Class ownerClass = Class.forName(className);   
  72.  4    
  73.  5     Class[] argsClass = new Class[args.length];   
  74.  6    
  75.  7     for (int i = 0, j = args.length; i < j; i++) {   
  76.  8         argsClass[i] = args[i].getClass();   
  77.  9     }   
  78. 10    
  79. 11     Method method = ownerClass.getMethod(methodName, argsClass);   
  80. 12    
  81. 13     return method.invoke(null, args);   
  82. 14 }   
  83.   
  84. 基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。   
  85.   
  86.   
  87.   
  88. 5. 新建实例   
  89.  1    
  90.  2 public Object newInstance(String className, Object[] args) throws Exception {   
  91.  3     Class newoneClass = Class.forName(className);   
  92.  4    
  93.  5     Class[] argsClass = new Class[args.length];   
  94.  6    
  95.  7     for (int i = 0, j = args.length; i < j; i++) {   
  96.  8         argsClass[i] = args[i].getClass();   
  97.  9     }   
  98. 10    
  99. 11     Constructor cons = newoneClass.getConstructor(argsClass);   
  100. 12    
  101. 13     return cons.newInstance(args);   
  102. 14    
  103. 15 }   
  104.   
  105. 这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。   
  106.   
  107. Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。   
  108.   
  109. 5~第9行:得到参数的Class数组。   
  110.   
  111. Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。   
  112.   
  113. cons.newInstance(args):新建实例。   
  114.   
  115.   
  116. 6. 判断是否为某个类的实例   
  117.   
  118. 1 public boolean isInstance(Object obj, Class cls) {   
  119. 2     return cls.isInstance(obj);   
  120. 3 }   
  121.   
  122.   
  123. 7. 得到数组中的某个元素   
  124. 1 public Object getByArray(Object array, int index) {   
  125. 2     return Array.get(array,index);   
  126. 3 }   
  127.   
  128.   
  129. 附完整源码:   
  130.   
  131. import java.lang.reflect.Array;   
  132. import java.lang.reflect.Constructor;   
  133. import java.lang.reflect.Field;   
  134. import java.lang.reflect.Method;   
  135.   
  136.   
  137. /**  
  138.  * Java Reflection Cookbook  
  139.  *  
  140.  * @author Michael Lee  
  141.  * @since 2006-8-23  
  142.  * @version 0.1a  
  143.  */  
  144.   
  145. public class Reflection {   
  146.     /**  
  147.      * 得到某个对象的公共属性  
  148.      *  
  149.      * @param owner, fieldName  
  150.      * @return 该属性对象  
  151.      * @throws Exception  
  152.      *  
  153.      */  
  154.     public Object getProperty(Object owner, String fieldName) throws Exception {   
  155.         Class ownerClass = owner.getClass();   
  156.   
  157.         Field field = ownerClass.getField(fieldName);   
  158.   
  159.         Object property = field.get(owner);   
  160.   
  161.         return property;   
  162.     }   
  163.   
  164.     /**  
  165.      * 得到某类的静态公共属性  
  166.      *  
  167.      * @param className   类名  
  168.      * @param fieldName   属性名  
  169.      * @return 该属性对象  
  170.      * @throws Exception  
  171.      */  
  172.     public Object getStaticProperty(String className, String fieldName)   
  173.             throws Exception {   
  174.         Class ownerClass = Class.forName(className);   
  175.   
  176.         Field field = ownerClass.getField(fieldName);   
  177.   
  178.         Object property = field.get(ownerClass);   
  179.   
  180.         return property;   
  181.     }   
  182.   
  183.   
  184.     /**  
  185.      * 执行某对象方法  
  186.      *  
  187.      * @param owner  
  188.      *            对象  
  189.      * @param methodName  
  190.      *            方法名  
  191.      * @param args  
  192.      *            参数  
  193.      * @return 方法返回值  
  194.      * @throws Exception  
  195.      */  
  196.     public Object invokeMethod(Object owner, String methodName, Object[] args)   
  197.             throws Exception {   
  198.   
  199.         Class ownerClass = owner.getClass();   
  200.   
  201.         Class[] argsClass = new Class[args.length];   
  202.   
  203.         for (int i = 0, j = args.length; i < j; i++) {   
  204.             argsClass[i] = args[i].getClass();   
  205.         }   
  206.   
  207.         Method method = ownerClass.getMethod(methodName, argsClass);   
  208.   
  209.         return method.invoke(owner, args);   
  210.     }   
  211.   
  212.   
  213.       /**  
  214.      * 执行某类的静态方法  
  215.      *  
  216.      * @param className  
  217.      *            类名  
  218.      * @param methodName  
  219.      *            方法名  
  220.      * @param args  
  221.      *            参数数组  
  222.      * @return 执行方法返回的结果  
  223.      * @throws Exception  
  224.      */  
  225.     public Object invokeStaticMethod(String className, String methodName,   
  226.             Object[] args) throws Exception {   
  227.         Class ownerClass = Class.forName(className);   
  228.   
  229.         Class[] argsClass = new Class[args.length];   
  230.   
  231.         for (int i = 0, j = args.length; i < j; i++) {   
  232.             argsClass[i] = args[i].getClass();   
  233.         }   
  234.   
  235.         Method method = ownerClass.getMethod(methodName, argsClass);   
  236.   
  237.         return method.invoke(null, args);   
  238.     }   
  239.   
  240.   
  241.   
  242.     /**  
  243.      * 新建实例  
  244.      *  
  245.      * @param className  
  246.      *            类名  
  247.      * @param args  
  248.      *            构造函数的参数  
  249.      * @return 新建的实例  
  250.      * @throws Exception  
  251.      */  
  252.     public Object newInstance(String className, Object[] args) throws Exception {   
  253.         Class newoneClass = Class.forName(className);   
  254.   
  255.         Class[] argsClass = new Class[args.length];   
  256.   
  257.         for (int i = 0, j = args.length; i < j; i++) {   
  258.             argsClass[i] = args[i].getClass();   
  259.         }   
  260.   
  261.         Constructor cons = newoneClass.getConstructor(argsClass);   
  262.   
  263.         return cons.newInstance(args);   
  264.   
  265.     }   
  266.   
  267.   
  268.        
  269.     /**  
  270.      * 是不是某个类的实例  
  271.      * @param obj 实例  
  272.      * @param cls 类  
  273.      * @return 如果 obj 是此类的实例,则返回 true  
  274.      */  
  275.     public boolean isInstance(Object obj, Class cls) {   
  276.         return cls.isInstance(obj);   
  277.     }   
  278.        
  279.     /**  
  280.      * 得到数组中的某个元素  
  281.      * @param array 数组  
  282.      * @param index 索引  
  283.      * @return 返回指定数组对象中索引组件的值  
  284.      */  
  285.     public Object getByArray(Object array, int index) {   
  286.         return Array.get(array,index);   
  287.     }   
  288. }  
Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫——反射。反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。

1. 得到某个对象的属性

1 public Object getProperty(Object owner, String fieldName) throws Exception {
2     Class ownerClass = owner.getClass();
3 
4     Field field = ownerClass.getField(fieldName);
5 
6     Object property = field.get(owner);
7 
8     return property;
9 }
Class ownerClass = owner.getClass():得到该对象的Class。

Field field = ownerClass.getField(fieldName):通过Class得到类声明的属性。

Object property = field.get(owner):通过对象得到该属性的实例,如果这个属性是非公有的,这里会报IllegalAccessException。



2. 得到某个类的静态属性

 1 public Object getStaticProperty(String className, String fieldName)
 2             throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Field field = ownerClass.getField(fieldName);
 6 
 7     Object property = field.get(ownerClass);
 8 
 9     return property;
10 }

Class ownerClass = Class.forName(className) :首先得到这个类的Class。

Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。

Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。


3. 执行某对象的方法

 1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
 2 
 3     Class ownerClass = owner.getClass();
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(owner, args);
14 }
Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。

5~9行:配置参数的Class数组,作为寻找Method的条件。

Method method = ownerClass.getMethod(methodName, argsClass):通过Method名和参数的Class数组得到要执行的Method。

method.invoke(owner, args):执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值。


4. 执行某个类的静态方法

 1 public Object invokeStaticMethod(String className, String methodName,
 2             Object[] args) throws Exception {
 3     Class ownerClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Method method = ownerClass.getMethod(methodName, argsClass);
12 
13     return method.invoke(null, args);
14 }

基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。



5. 新建实例
 1 
 2 public Object newInstance(String className, Object[] args) throws Exception {
 3     Class newoneClass = Class.forName(className);
 4 
 5     Class[] argsClass = new Class[args.length];
 6 
 7     for (int i = 0, j = args.length; i < j; i++) {
 8         argsClass[i] = args[i].getClass();
 9     }
10 
11     Constructor cons = newoneClass.getConstructor(argsClass);
12 
13     return cons.newInstance(args);
14 
15 }

这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。

Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。

第5~第9行:得到参数的Class数组。

Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。

cons.newInstance(args):新建实例。


6. 判断是否为某个类的实例

1 public boolean isInstance(Object obj, Class cls) {
2     return cls.isInstance(obj);
3 }


7. 得到数组中的某个元素
1 public Object getByArray(Object array, int index) {
2     return Array.get(array,index);
3 }


附完整源码:

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


/**
 * Java Reflection Cookbook
 *
 * @author Michael Lee
 * @since 2006-8-23
 * @version 0.1a
 */

public class Reflection {
    /**
     * 得到某个对象的公共属性
     *
     * @param owner, 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);

        return property;
    }

    /**
     * 得到某类的静态公共属性
     *
     * @param className   类名
     * @param fieldName   属性名
     * @return 该属性对象
     * @throws Exception
     */
    public Object getStaticProperty(String className, String fieldName)
            throws Exception {
        Class ownerClass = Class.forName(className);

        Field field = ownerClass.getField(fieldName);

        Object property = field.get(ownerClass);

        return property;
    }


    /**
     * 执行某对象方法
     *
     * @param owner
     *            对象
     * @param methodName
     *            方法名
     * @param args
     *            参数
     * @return 方法返回值
     * @throws Exception
     */
    public Object invokeMethod(Object owner, String methodName, Object[] args)
            throws Exception {

        Class ownerClass = owner.getClass();

        Class[] argsClass = new Class[args.length];

        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

        Method method = ownerClass.getMethod(methodName, argsClass);

        return method.invoke(owner, args);
    }


      /**
     * 执行某类的静态方法
     *
     * @param className
     *            类名
     * @param methodName
     *            方法名
     * @param args
     *            参数数组
     * @return 执行方法返回的结果
     * @throws Exception
     */
    public Object invokeStaticMethod(String className, String methodName,
            Object[] args) throws Exception {
        Class ownerClass = Class.forName(className);

        Class[] argsClass = new Class[args.length];

        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

        Method method = ownerClass.getMethod(methodName, argsClass);

        return method.invoke(null, args);
    }



    /**
     * 新建实例
     *
     * @param className
     *            类名
     * @param args
     *            构造函数的参数
     * @return 新建的实例
     * @throws Exception
     */
    public Object newInstance(String className, Object[] args) throws Exception {
        Class newoneClass = Class.forName(className);

        Class[] argsClass = new Class[args.length];

        for (int i = 0, j = args.length; i < j; i++) {
            argsClass[i] = args[i].getClass();
        }

        Constructor cons = newoneClass.getConstructor(argsClass);

        return cons.newInstance(args);

    }


    
    /**
     * 是不是某个类的实例
     * @param obj 实例
     * @param cls 类
     * @return 如果 obj 是此类的实例,则返回 true
     */
    public boolean isInstance(Object obj, Class cls) {
        return cls.isInstance(obj);
    }
    
    /**
     * 得到数组中的某个元素
     * @param array 数组
     * @param index 索引
     * @return 返回指定数组对象中索引组件的值
     */
    public Object getByArray(Object array, int index) {
        return Array.get(array,index);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值