Java 反射例子详解

Java编程 的动态性,第 2部分: 引入反射

http://www.ibm.com/developerworks/cn/java/j-dyn0603/
转载至:
http://orangewhy.iteye.com/blog/56011
Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫——反射。反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。

  1. 得到某个对象的属性
    1
    2
    3
    4
    5
    6
    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;
    }

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

  1. 得到某个类的静态属性
    1
    2
    3
    4
    5
    6
    7
    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;
    }

Class ownerClass = Class.forName(className) :首先得到这个类的Class。
Field field = ownerClass.getField(fieldName):和上面一样,通过Class得到类声明的属性。
Object property = field.get(ownerClass) :这里和上面有些不同,因为该属性是静态的,所以直接从类的Class里取。

  1. 执行某对象的方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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);
    }

Class owner_class = owner.getClass() :首先还是必须得到这个对象的Class。
3~6行:配置参数的Class数组,作为寻找Method的条件。
Method method = ownerClass.getMethod(methodName, argsClass):通过Method名和参数的Class数组得到要执行的Method。
method.invoke(owner, args):执行该Method,invoke方法的参数是执行这个方法的对象,和参数数组。返回值是Object,也既是该方法的返回值。

  1. 执行某个类的静态方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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);
    }

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

  1. 新建实例
    1
    2
    3
    4
    5
    6
    7
    8
    9
    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);
    }

这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用newoneClass.newInstance()来实现。
Class newoneClass = Class.forName(className):第一步,得到要构造的实例的Class。
第6~第10行:得到参数的Class数组。
Constructor cons = newoneClass.getConstructor(argsClass):得到构造子。
cons.newInstance(args):新建实例。

  1. 判断是否为某个类的实例
    1
    2
    3
    public boolean isInstance(Object obj, Class cls) {
    return cls.isInstance(obj);
    }
  1. 得到数组中的某个元素
    public Object getByArray(Object array, int index) {
        return Array.get(array,index);
    }
    附完整源码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    import java.lang.reflect.Array;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    /**
    * Java Reflection Cookbook
    */
    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);
    }
    }
坚持原创及高品质技术分享,您的支持将鼓励我继续创作!