@Yano
2016-03-31T01:43:19.000000Z
字数 5201
阅读 2443
Java
反射(Reflection)能够让运行于 JVM 中的程序检测和修改运行时的行为。
在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。虚拟机利用运行时信息选择相应的方法执行。可以通过专门的Java类访问这些信息,保存这些信息的类被称为Class。
将Class类中的forName和newInstance配合使用,可以根据存储在字符串中的类名创建一个对象。
String s = "java.util.Date";Object m = Class.forName(s).newInstance();
通过反射,我们能够
JUnit通过反射来遍历包含 @Test 注解的方法,并在运行单元测试时调用它们。
开发人员可以在配置文件中定义对各种接口和类的实现。通过反射机制,框架能够快速地动态初始化所需要的类。
Spring框架使用如下的配置文件:
<bean id="someID" class="com.programcreek.Foo"><property name="someField" value="someValue" /></bean>
当Spring容器处理 bean 元素时,会使用Class.forName("com.programcreek.Foo")来初始化这个类,并再次使用反射获取 property 元素对应的setter方法,为对象的属性赋值。
<servlet><servlet-name>someServlet</servlet-name><servlet-class>com.programcreek.WhyReflectionServlet</servlet-class><servlet>
本着不重复造轮子的原则,API 详细参考自 这里,下面只做简单介绍。
在java.lang.reflect包中有三个重要的类:
对于public域(包括超类成员):
对于其它域(包括私有和受保护的成员,不包括超类成员):
下面介绍 Java 反射的使用,其中 Person 类及测试完整代码在本文最后。
// 加载类的3种方法Class clazz = Class.forName("com.yano.reflect.Person");Class clazz1 = new Person().getClass();Class class2 = Person.class;
Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);
Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getDeclaredConstructor(new Class[] { String.class });// 由于构造函数是 private 的,所以需要屏蔽Java语言的访问检查c.setAccessible(true);Person p = (Person) c.newInstance(new Object[] { "I'm a reflect name!" });
Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);Method method = clazz.getMethod("fun", null);method.invoke(p, null);
Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);Method method = clazz.getMethod("fun", new Class[] { String.class });method.invoke(p, new Object[] { "I'm a reflect method!" });
Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getDeclaredConstructor(new Class[] { String.class });// 由于构造函数是 private 的,所以需要获取控制权限c.setAccessible(true);Person p = (Person) c.newInstance(new Object[] { "I'm a reflect name!" });Field f = clazz.getField("name");Object value = f.get(p);Class type = f.getType();System.out.println(type);if (type.equals(String.class)) {System.out.println((String) value);}
Person 类
package com.yano.reflect;public class Person {public String name = "default name";public int[] array = new int[10];public Person() {System.out.println(name);for (int i = 0; i < array.length; i++) {array[i] = i;}}private Person(String name) {this.name = name;System.out.println(name);}public void fun() {System.out.println("fun");}public void fun(String name) {System.out.println(name);}}
test 类
package com.yano.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class test {/*** 反射:加载类的字节码** @throws SecurityException* @throws NoSuchMethodException*/public static void main(String[] args) throws Exception {refGetClass();// 获取并调用无参构造函数refGetPublicConstructor();// 获取并调用私有的含参构造函数refGetPrivateConstructor();// 获取并调用无参方法 funrefGetMethodWithNoArg();// 获取并调用有参数方法 funrefGetMethodWithArg();// 获取类的字段refGetField();}private static void refGetField() throws Exception {Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getDeclaredConstructor(new Class[] { String.class });// 由于构造函数是 private 的,所以需要获取控制权限c.setAccessible(true);Person p = (Person) c.newInstance(new Object[] { "I'm a reflect name!" });Field f = clazz.getField("name");Object value = f.get(p);Class type = f.getType();System.out.println(type);if (type.equals(String.class)) {System.out.println((String) value);}System.out.println();}private static void refGetMethodWithArg() throws Exception {Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);Method method = clazz.getMethod("fun", new Class[] { String.class });method.invoke(p, new Object[] { "I'm a reflect method!" });System.out.println();}private static void refGetMethodWithNoArg() throws Exception {Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);Method method = clazz.getMethod("fun", null);method.invoke(p, null);System.out.println();}private static void refGetPrivateConstructor() throws Exception {Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getDeclaredConstructor(new Class[] { String.class });// 由于构造函数是 private 的,所以需要屏蔽Java语言的访问检查c.setAccessible(true);Person p = (Person) c.newInstance(new Object[] { "I'm a reflect name!" });System.out.println();}private static void refGetPublicConstructor() throws Exception {Class clazz = Class.forName("com.yano.reflect.Person");Constructor c = clazz.getConstructor(null);Person p = (Person) c.newInstance(null);System.out.println();}private static void refGetClass() throws ClassNotFoundException {// 加载类的3种方法Class clazz = Class.forName("com.yano.reflect.Person");Class clazz1 = new Person().getClass();Class class2 = Person.class;System.out.println();}}
本文参考自:
1. http://www.programcreek.com/2013/09/java-reflection-tutorial/
2. http://www.importnew.com/9078.html
3. 《Java 核心技术 卷 I》第 5 章