跟着刚哥梳理java知识点——反射和代理(十七)
Posted 锲而不舍,金石可镂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跟着刚哥梳理java知识点——反射和代理(十七)相关的知识,希望对你有一定的参考价值。
反射机制是什么?
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有的属性和方法
;对于任意一个对象,都能够调用他的一个方法和属性,这种动态获取的信息以及
动态调用对象的方法的功能称为java语言的反射机制。
反射机制能做什么?
反射机制主要提供以下功能
√ 在运行时判断任意一个对象所属的类
√ 在运行时构造任意一个类的对象
√ 在运行时判断任意一个类所具有的的属性和方法
√ 在运行时调用一个对象的方法
√ 生成动态代理
通过一个对象获得完整的包名和类名
package com.hzg; public class TestReflect { public static void main(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 void main(String[] args) throws Exception { Class<?> class1 = null; Class<?> class2 = null; Class<?> class3 = 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{ 2 void productCloth(); 3 } 4 //被代理类 5 class NikeClothFactory implements ClothFactory{ 6 @Override 7 public void productCloth(){ 8 sysytem.out.printLn("NIKE工厂生产一批衣服"); 9 } 10 } 11 //代理类 12 class ProxyFactory implements ClothFactory{ 13 ClothFactory cf; 14 public ProxyFactory(ClothFactory cf){ 15 this.cf = cf; 16 } 17 @Override 18 public void productCloth(){ 19 sysytem.out.printLn("代理类开始执行,收代理费1000"); 20 cf.productCloth(); 21 } 22 } 23 24 public class Test{ 25 public static void main(String[] args){ 26 //① 创建一个被代理对象 27 NikeClothFactory nike = new NikeClothFactory (); 28 //② 创建一个代理类对象 29 ProxyFactory proxy = new ProxyFactory(nike); 30 //③ 调用代理类对象的方法 31 proxy.productCloth(); 32 } 33 }
静态代理总结:
① 代理类和被代理类都实现同一个接口
② 代理类和被代理类都实现接口中的方法
2、动态代理(基于反射实现的动态代理)
1 interface ClothFactory{ 2 void productCloth(); 3 } 4 //被代理类 5 class NikeClothFactory inplements ClothFactory{ 6 @Override 7 public void productCloth(){ 8 sysytem.out.printLn("NIKE工厂生产一批衣服"); 9 } 10 } 11 //①必须实现InvocationHandler接口 12 class MyInvocationHandler implements InvocationHandler{ 13 //② 声明接口的代理类 14 Object obj; 15 //③ 创建一个方法实例化代理类 16 public Object bind(Object obj){ 17 this.obj = obj; 18 return Proxy.newProxyInstance( 19 obj.getClass().geyClassLoder(), 20 obj.getClass().getInterfaces(),this); 21 } 22 //④ 实现接口InvacationHandler的方法 23 // 此方法实现:当调用代理类的对象方法的时候,都会转换到它上调用 24 @Override 25 public Object invoke(Object proxy,Method method,Object[] args){ 26 Object returnVal = method.invoke(obj,args); 27 return returnVal(); 28 } 29 } 30 //调用实现一下 31 public class Test{ 32 public static void main(String[] args){ 33 //① 老规矩:创建一个被代理对象 34 NikeClothFactory nike = new NikeClothFactory (); 35 //②老规矩:创建一个代理类对象 36 MyInvocationHandler hander = new MyinvocationHanlder(); 37 ClothFactory proxyCloth = (ClothFactory)hander.bind(nike); 38 //③ 老规矩:调用代理类对象的方法 39 proxyCloth .productCloth(); 40 } 41 }
以上是关于跟着刚哥梳理java知识点——反射和代理(十七)的主要内容,如果未能解决你的问题,请参考以下文章