一、什么是反射机制
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 }