设为首页收藏本站

Scripts 学盟

 找回密码
 加入学盟

QQ登录

只需一步,快速开始

查看: 1179|回复: 4
打印 上一主题 下一主题

Java反射经典实例 Java Reflection [复制链接]

Rank: 8Rank: 8

跳转到指定楼层
1#
那个谁 发表于 2011-8-10 10:38:32 |只看该作者 |倒序浏览
Java提供了一套机制来动态执行方法和构造方法,以及数组操作等,这套机制就叫——反射。反射机制是如今很多流行框架的实现基础,其中包括Spring、Hibernate等。原理性的问题不是本文的重点,接下来让我们在实例中学习这套精彩的机制。

1. 得到某个对象的属性
  1. public Object getProperty(Object owner, String fieldName) throws Exception {
  2.     Class ownerClass = owner.getClass();

  3.      Field field = ownerClass.getField(fieldName);

  4.      Object property = field.get(owner);

  5.      return property;
  6. }
复制代码
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.      Field field = ownerClass.getField(fieldName);

  5.      Object property = field.get(ownerClass);

  6.      return property;
  7. }
复制代码
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.       Class ownerClass = owner.getClass();
  3.   
  4.       Class[] argsClass = new Class[args.length];
  5.   
  6.       for (int i = 0, j = args.length; i < j; i++) {
  7.          argsClass[i] = args[i].getClass();
  8.      }

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

  10.      return method.invoke(owner, args);
  11. }
复制代码
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.       for (int i = 0, j = args.length; i < j; i++) {
  7.           argsClass[i] = args[i].getClass();
  8.      }

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

  10.      return method.invoke(null, args);
  11. }
复制代码
基本的原理和实例3相同,不同点是最后一行,invoke的一个参数是null,因为这是静态方法,不需要借助实例运行。



5. 新建实例
  1.   public Object newInstance(String className, Object[] args) throws Exception {
  2.       Class newoneClass = Class.forName(className);
  3.   
  4.       Class[] argsClass = new Class[args.length];
  5.      for (int i = 0, j = args.length; i < j; i++) {
  6.        argsClass[i] = args[i].getClass();
  7.       }

  8.     Constructor cons = newoneClass.getConstructor(argsClass);

  9.     return cons.newInstance(args);

  10. }
复制代码
这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用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. }
复制代码
附完整源码:
  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. * Java Reflection Cookbook
  7. *
  8. * @author Michael Lee
  9. * @since 2006-8-23
  10. * @version 0.1a
  11. */

  12. public class Reflection {
  13.     /**
  14.      * 得到某个对象的公共属性
  15.      *
  16.      * @param owner, fieldName
  17.      * @return 该属性对象
  18.      * @throws Exception
  19.      *
  20.      */
  21.     public Object getProperty(Object owner, String fieldName) throws Exception {
  22.         Class ownerClass = owner.getClass();

  23.         Field field = ownerClass.getField(fieldName);

  24.         Object property = field.get(owner);

  25.         return property;
  26.     }

  27.     /**
  28.      * 得到某类的静态公共属性
  29.      *
  30.      * @param className   类名
  31.      * @param fieldName   属性名
  32.      * @return 该属性对象
  33.      * @throws Exception
  34.      */
  35.     public Object getStaticProperty(String className, String fieldName)
  36.             throws Exception {
  37.         Class ownerClass = Class.forName(className);

  38.         Field field = ownerClass.getField(fieldName);

  39.         Object property = field.get(ownerClass);

  40.         return property;
  41.     }


  42.     /**
  43.      * 执行某对象方法
  44.      *
  45.      * @param owner
  46.      *            对象
  47.      * @param methodName
  48.      *            方法名
  49.      * @param args
  50.      *            参数
  51.      * @return 方法返回值
  52.      * @throws Exception
  53.      */
  54.     public Object invokeMethod(Object owner, String methodName, Object[] args)
  55.             throws Exception {

  56.         Class ownerClass = owner.getClass();

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

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

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

  62.         return method.invoke(owner, args);
  63.     }


  64.       /**
  65.      * 执行某类的静态方法
  66.      *
  67.      * @param className
  68.      *            类名
  69.      * @param methodName
  70.      *            方法名
  71.      * @param args
  72.      *            参数数组
  73.      * @return 执行方法返回的结果
  74.      * @throws Exception
  75.      */
  76.     public Object invokeStaticMethod(String className, String methodName,
  77.             Object[] args) throws Exception {
  78.         Class ownerClass = Class.forName(className);

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

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

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

  84.         return method.invoke(null, args);
  85.     }



  86.     /**
  87.      * 新建实例
  88.      *
  89.      * @param className
  90.      *            类名
  91.      * @param args
  92.      *            构造函数的参数
  93.      * @return 新建的实例
  94.      * @throws Exception
  95.      */
  96.     public Object newInstance(String className, Object[] args) throws Exception {
  97.         Class newoneClass = Class.forName(className);

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

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

  102.         Constructor cons = newoneClass.getConstructor(argsClass);

  103.         return cons.newInstance(args);

  104.     }


  105.    
  106.     /**
  107.      * 是不是某个类的实例
  108.      * @param obj 实例
  109.      * @param cls 类
  110.      * @return 如果 obj 是此类的实例,则返回 true
  111.      */
  112.     public boolean isInstance(Object obj, Class cls) {
  113.         return cls.isInstance(obj);
  114.     }
  115.    
  116.     /**
  117.      * 得到数组中的某个元素
  118.      * @param array 数组
  119.      * @param index 索引
  120.      * @return 返回指定数组对象中索引组件的值
  121.      */
  122.     public Object getByArray(Object array, int index) {
  123.         return Array.get(array,index);
  124.     }
  125. }
复制代码
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
分享分享0 收藏收藏0

管理员

超级大菜鸟

Rank: 9Rank: 9Rank: 9

2#
混混@普宁.中国 实名认证  发表于 2011-8-10 10:58:48 |只看该作者
good ,  杰杰来加分

使用道具 举报

Rank: 8Rank: 8

3#
那个谁 发表于 2011-8-10 11:14:11 |只看该作者
混混@普宁.中国 发表于 2011-8-10 10:58
good ,  杰杰来加分

分呢。。在哪 啊

使用道具 举报

Rank: 8Rank: 8

4#
momo 发表于 2011-8-10 14:05:55 |只看该作者
倒分倒分,过了十五号,开砖厂给杰杰
过了爱做梦的年纪
轰轰烈烈不如平静

使用道具 举报

Rank: 7Rank: 7Rank: 7

5#
俊俊 实名认证  发表于 2011-8-10 23:54:39 |只看该作者
C#中也有反射,,,可以动态执行代码,,,就像编译器一样,先编译后执行。。。

使用道具 举报

您需要登录后才可以回帖 登录 | 加入学盟

手机版|Scripts 学盟   |

GMT+8, 2024-5-9 14:45 , Processed in 1.060306 second(s), 11 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部