Java反射经典实例

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. public Object newInstance(String className, Object[] args) throws Exception {  
  2.      Class newoneClass = Class.forName(className);  
  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.    
  10.      Constructor cons = newoneClass.getConstructor(argsClass);  
  11.    
  12.      return cons.newInstance(args);  
  13.    
  14. }  

这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数,可以直接使用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. /** 
  7. * Java Reflection Cookbook 
  8. * 
  9. * @author Michael Lee 
  10. * @since 2006-8-23 
  11. * @version 0.1a 
  12. */  
  13. public class Reflection {  
  14.     /** 
  15.      * 得到某个对象的公共属性 
  16.      * 
  17.      * @param owner, fieldName 
  18.      * @return 该属性对象 
  19.      * @throws Exception 
  20.      * 
  21.      */  
  22.     public Object getProperty(Object owner, String fieldName) throws Exception {  
  23.         Class ownerClass = owner.getClass();  
  24.         Field field = ownerClass.getField(fieldName);  
  25.         Object property = field.get(owner);  
  26.         return property;  
  27.     }  
  28.     /** 
  29.      * 得到某类的静态公共属性 
  30.      * 
  31.      * @param className   类名 
  32.      * @param fieldName   属性名 
  33.      * @return 该属性对象 
  34.      * @throws Exception 
  35.      */  
  36.     public Object getStaticProperty(String className, String fieldName)  
  37.             throws Exception {  
  38.         Class ownerClass = Class.forName(className);  
  39.         Field field = ownerClass.getField(fieldName);  
  40.         Object property = field.get(ownerClass);  
  41.         return property;  
  42.     }  
  43.   
  44.     /** 
  45.      * 执行某对象方法 
  46.      * 
  47.      * @param owner 
  48.      *            对象 
  49.      * @param methodName 
  50.      *            方法名 
  51.      * @param args 
  52.      *            参数 
  53.      * @return 方法返回值 
  54.      * @throws Exception 
  55.      */  
  56.     public Object invokeMethod(Object owner, String methodName, Object[] args)  
  57.             throws Exception {  
  58.         Class ownerClass = owner.getClass();  
  59.         Class[] argsClass = new Class[args.length];  
  60.         for (int i = 0, j = args.length; i < j; i++) {  
  61.             argsClass[i] = args[i].getClass();  
  62.         }  
  63.         Method method = ownerClass.getMethod(methodName, argsClass);  
  64.         return method.invoke(owner, args);  
  65.     }  
  66.   
  67.       /** 
  68.      * 执行某类的静态方法 
  69.      * 
  70.      * @param className 
  71.      *            类名 
  72.      * @param methodName 
  73.      *            方法名 
  74.      * @param args 
  75.      *            参数数组 
  76.      * @return 执行方法返回的结果 
  77.      * @throws Exception 
  78.      */  
  79.     public Object invokeStaticMethod(String className, String methodName,  
  80.             Object[] args) throws Exception {  
  81.         Class ownerClass = Class.forName(className);  
  82.         Class[] argsClass = new Class[args.length];  
  83.         for (int i = 0, j = args.length; i < j; i++) {  
  84.             argsClass[i] = args[i].getClass();  
  85.         }  
  86.         Method method = ownerClass.getMethod(methodName, argsClass);  
  87.         return method.invoke(null, args);  
  88.     }  
  89.     /** 
  90.      * 新建实例 
  91.      * 
  92.      * @param className 
  93.      *            类名 
  94.      * @param args 
  95.      *            构造函数的参数 
  96.      * @return 新建的实例 
  97.      * @throws Exception 
  98.      */  
  99.     public Object newInstance(String className, Object[] args) throws Exception {  
  100.         Class newoneClass = Class.forName(className);  
  101.         Class[] argsClass = new Class[args.length];  
  102.         for (int i = 0, j = args.length; i < j; i++) {  
  103.             argsClass[i] = args[i].getClass();  
  104.         }  
  105.         Constructor cons = newoneClass.getConstructor(argsClass);  
  106.         return cons.newInstance(args);  
  107.     }  
  108.   
  109.       
  110.     /** 
  111.      * 是不是某个类的实例 
  112.      * @param obj 实例 
  113.      * @param cls 类 
  114.      * @return 如果 obj 是此类的实例,则返回 true 
  115.      */  
  116.     public boolean isInstance(Object obj, Class cls) {  
  117.         return cls.isInstance(obj);  
  118.     }  
  119.       
  120.     /** 
  121.      * 得到数组中的某个元素 
  122.      * @param array 数组 
  123.      * @param index 索引 
  124.      * @return 返回指定数组对象中索引组件的值 
  125.      */  
  126.     public Object getByArray(Object array, int index) {  
  127.         return Array.get(array,index);  
  128.     }  
  129. }  

你可能感兴趣的:(Java反射经典实例)