反射机制是什么?反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有的属性和方法;对于任意一个对象,都能够调用他的一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
反射机制能做什么?反射机制主要提供以下功能√ 在运行时判断任意一个对象所属的类√ 在运行时构造任意一个类的对象√ 在运行时判断任意一个类所具有的的属性和方法√ 在运行时调用一个对象的方法√ 生成动态代理
- package com.hzg;
- public class TestReflect {
- public static voidmain(String[] args)throws Exception {
- TestReflect testReflect =new TestReflect();
- System.out.println(testReflect.getClass().getName());
- // 结果 com.hzg.TestReflect
- }
- }
- Class clazz = Person.class();
- //1、创建clazz对象的运行时类Person对象Person p = (Person)clazz.getInstance();
- //2、通过反射调用运行时的指定属性Filed f1 = clazz.getField("name");
- f1.set(p,"LiudeHua");
- //3、通过反射调用运行时的指定的方法Method m1 = clazz.getMethod("show",String.class);
- m1.invoke(p,"CHN");
注意:Class 可不是关键字 class,Class 是类名字,class 是个关键字标识是类
获取 class 的实例(3 种方式)①调用运行时类本身的. class 属性 Class clazz = Person.class;②通过运行时类的对象获取 Person p = new Person();Class clazz = p.getClass();③通过 class 的静态方法获取 Class clazz = Class.forName("com.hzg.TestReflect");
- package com.hzg;
- public class TestReflect {
- public static voidmain(String[] args)throws Exception {
- Classclass1 =null;
- Classclass2 =null;
- Classclass3 =null;
- // ① 静态方法(一般采用这种形式)class1 = Class.forName("com.hzg.TestReflect");
- // ② 运行时类的对象获取class2 =new TestReflect().getClass();
- // ③ 类本身.class属性class3 = TestReflect.class;
- System.out.println("类名称 " + class1.getName());
- System.out.println("类名称 " + class2.getName());
- System.out.println("类名称 " + class3.getName());
- }
- }
- 1 package com.hzg;
- 2 import java.io.Serializable;
- 3 public class TestReflect implements Serializable {
- 4 private static final long serialVersionUID = -2862585049955236662L;
- 5 public static void main(String[] args) throws Exception {
- 6 Class clazz = Class.forName("com.hzg.TestReflect");
- 7 // 取得父类
- 8 Class parentClass = clazz.getSuperclass();
- 9 System.out.println("clazz的父类为:" + parentClass.getName());
- 10 // clazz的父类为: java.lang.Object
- 11 // 获取所有的接口
- 12 Class intes[] = clazz.getInterfaces();
- 13 System.out.println("clazz实现的接口有:");
- 14
- for (int i = 0; i < intes.length; i++) {
- 15 System.out.println((i + 1) + ":" + intes[i].getName());
- 16
- }
- 17
- }
- 18
- }
有了 class 实例以后,可以做什么呢?① 可以创建对应运行时类的对象② 获取对应运行是类的完整的类的结构:属性、方法、构造器、包、泛型、注解、异常、内部类。如 Method[] m1 = clazz.getMethods():获取类和父类的所有 public 方法 Method[] m1 = clazz.getDeclaredMethods():所有修饰符方法 但是不含父类,只有这个类的中所有修饰符方法③ 调用运行是类中指定的结构(属性、方法、构造器)√ 获取指定属性:Field name = clazz.getField("name");√ 设置指定 public 属性:name.set(p,"hzg"); √ 设置指定 private 属性:Field name = clazz.geDeclaredtField("name");name.setAccessible(true);name.set(p,"hzg");√ 获取指定的方法:Method m1 = clazz.getMethod("show");√ 调用指定的方法:Object obj = m1.invoke(p); 返回类型就是方法的返回类型
√ 调用静态方法:m1.invoke(Person.class);√ 调用带参数的指定方法:Method m1 = clazz.getDeclatedMethod("show1",String.class);Object obj = m1.invoke(p,"hzg");
√ 调用构造器:Constructor con = clazz.getDeclaredConstructor();√ 调用带参数构造器,和带参数方法一致
Java 反射的应用 --- 代理
1、静态代理(基于接口的多态性实现的静态代理)
- 1 interface ClothFactory {
- 2void productCloth();
- 3
- }
- 4 //被代理类
- 5 class NikeClothFactory implements ClothFactory {
- 6@Override 7public void productCloth() {
- 8sysytem.out.printLn("NIKE工厂生产一批衣服");
- 9
- }
- 10
- }
- 11 //代理类
- 12 class ProxyFactory implements ClothFactory {
- 13ClothFactory cf;
- 14public ProxyFactory(ClothFactory cf) {
- 15this.cf = cf;
- 16
- }
- 17@Override 18public void productCloth() {
- 19sysytem.out.printLn("代理类开始执行,收代理费1000");
- 20cf.productCloth();
- 21
- }
- 22
- }
- 23 24 public class Test {
- 25public static void main(String[] args) {
- 26 //① 创建一个被代理对象
- 27NikeClothFactory nike = new NikeClothFactory();
- 28 //② 创建一个代理类对象
- 29ProxyFactory proxy = new ProxyFactory(nike);
- 30 //③ 调用代理类对象的方法
- 31proxy.productCloth();
- 32
- }
- 33
- }
静态代理总结:① 代理类和被代理类都实现同一个接口② 代理类和被代理类都实现接口中的方法
2、动态代理(基于反射实现的动态代理)
- 1 interface ClothFactory {
- 2void productCloth();
- 3
- }
- 4 //被代理类
- 5 class NikeClothFactory inplements ClothFactory {
- 6@Override 7public void productCloth() {
- 8sysytem.out.printLn("NIKE工厂生产一批衣服");
- 9
- }
- 10
- }
- 11 //①必须实现InvocationHandler接口
- 12 class MyInvocationHandler implements InvocationHandler {
- 13 //② 声明接口的代理类
- 14Object obj;
- 15 //③ 创建一个方法实例化代理类
- 16public Object bind(Object obj) {
- 17this.obj = obj;
- 18
- return Proxy.newProxyInstance(19obj.getClass().geyClassLoder(), 20obj.getClass().getInterfaces(), this);
- 21
- }
- 22 //④ 实现接口InvacationHandler的方法
- 23 // 此方法实现:当调用代理类的对象方法的时候,都会转换到它上调用
- 24@Override 25public Object invoke(Object proxy, Method method, Object[] args) {
- 26Object returnVal = method.invoke(obj, args);
- 27
- return returnVal();
- 28
- }
- 29
- }
- 30 //调用实现一下
- 31 public class Test {
- 32public static void main(String[] args) {
- 33 //① 老规矩:创建一个被代理对象
- 34NikeClothFactory nike = new NikeClothFactory();
- 35 //②老规矩:创建一个代理类对象
- 36MyInvocationHandler hander = new MyinvocationHanlder();
- 37ClothFactory proxyCloth = (ClothFactory) hander.bind(nike);
- 38 //③ 老规矩:调用代理类对象的方法
- 39proxyCloth.productCloth();
- 40
- }
- 41
- }
来源: http://www.cnblogs.com/hzg110/p/6707030.html