标签:
一、什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能,称为java语言的反射机制。
二、反射的应用
1.Spring框架:IOC(控制反转)
2.Hibernate框架:关联映射等
3.白盒测试
三、相关的API
1.java.lang包下
Class<T> : 表示一个正在运行的java应用程序中的类和接口,是Reflection的起源。
2.java.lang.reflect包下
Field类 : 代表类的成员变量,也称类的属性。
Method类 : 代表类的方法。
Constructor类 : 代表类的构造方法。
Array类 : 提供了动态创建数组,以及访问数组元素的静态方法。
四、关于Class<T>
类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象。
Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的,因此不能显式地声明一个Class对象。
Class是Reflection的起源。要想操纵类中的属性和方法,都必须从获取Class Object开始,获取方式如下表。
获取方式 |
说明 |
示例 |
Object.getClass() |
获取指定实例对象的Class |
List li = new ArrayList(); Class liCla = li.getClass(); |
Class.getSuperclass() |
获取当前Class的继承类Class |
List li = new ArrayList(); Class liCla = li.getClass(); Class suCla = liCla.getSuperclass(); |
Object.class |
.class直接获取 |
Class liCla = ArrayList.class; |
Class.forName("类名") |
用class的静态方法,传入类的全称即可 |
Class cla = Class.forName("java.util.ArrayList"); |
Primitive.TYPE |
基本数据类型的封装类获取Class的方式 |
Class longClass = Long.TYPE; Class inteClass = Integer.TYPE; |
五、反射的使用
创建反射操作的目标。
package reflection; public class BaseUser { private String baseId; public String getBaseId() { return baseId; } public void setBaseId(String baseId) { this.baseId = baseId; } }
package reflection; public class User extends BaseUser { private String id; public String name; public User() { } public User(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package reflection; public class Reflection { public String pubField; public void test1() { System.out.println("这是一个public method!"); } public void test2(String test) { System.out.println("这是一个带参 public method!参数为:" + test); } }
(a)通过反射实例化对象
1.实例化无参构造函数的对象。
2.实例化带参构造函数的对象。
package reflection; public class Demo { public static void main(String[] args) { Class<?> cla = User.class; try { User u1 = (User) cla.newInstance(); System.out.println("实例化无参构造函数的对象,方式一:" + u1); User u2 = (User) cla.getConstructor().newInstance(); System.out.println("实例化无参构造函数的对象,方式二:" + u2); User u3 = (User) cla.getConstructor(String.class).newInstance("有参"); System.out.println("实例化有参构造函数的对象:" + u3 + " name:" + u3.getName()); User u4 = new User(); System.out.println("常实例化对象:" + u4); } catch (Exception e) { e.printStackTrace(); } } }
(b)通过反射调用Method
package reflection; import java.lang.reflect.Method; public class RefMethodTest { public static void main(String[] args) throws Exception{ Class<?> clazz = Reflection.class; Object obj = clazz.newInstance(); System.out.println("获得当前类所申明的指定的方法,test1():"); Method m1 = clazz.getDeclaredMethod("test1"); System.out.println("方法名为:" + m1.getName()); System.out.println("运行该方法:"); m1.invoke(obj); System.out.println("获得当前类所声明的指定的方法,test2():"); Method m2 = clazz.getDeclaredMethod("test2", String.class); System.out.println("方法名为:" + m2.getName()); System.out.println("运行该方法"); m2.invoke(obj, "这是参数"); } }
(c)通过反射调用Field
package reflection; import java.lang.reflect.Field; public class RefFieldTest { public static void main(String[] args) throws Exception{ Class<?> clazz = Reflection.class; Object obj = clazz.newInstance(); System.out.println("获得当前类以及超类指定的属性,pubField:"); Field f = clazz.getDeclaredField("pubField"); System.out.println("属性名:" + f.getName()); System.out.println("通过反射动态设定Field的值"); f.set(obj, "新的值"); System.out.println("通过反射动态获取Field的值"); System.out.println("Field的值为:" + f.get(obj)); } }
标签:
原文地址:http://www.cnblogs.com/wscy/p/4709267.html