在上一篇博文中我们已经进行了反射机制的习题练习,这里我们在做一个考察比较全面的练习,如下:
写一个类ReflectUtil类, 类中写一个静态方法Object methodInvoker(String classMethd) 此方法为无参方法如,
我们传入的实参字符串为:classMethod "java.lang.String.length()"就可以通过反射执行String类中的length方法、当传入的实参字符串为"com.atguigu.javase.reflect.Teacher.test()"就可以执行指定包下,指定类中的指定方法。
具体实现如下:
package com.aguigu.javase.work; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /* 写一个类ReflectUtil类, 类中写一个静态方法Object methodInvoker(String classMethd) 此方法为无参方法如: classMethod "java.lang.String.length()" com.atguigu.javase.reflect.Teacher.test() */ public class ReflectUtil { public static Object methodInvoker(String classMethd) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 获取最后一个"."出现的下标 int lastDot = classMethd.lastIndexOf("."); // 获取子字符串从第0下标到最后一个"."出现的下标,这个字符串即为类的全限定名称 String className = classMethd.substring(0, lastDot); // 获取子字符串,为方法的名称 String methodName = classMethd.substring(lastDot + 1, classMethd.length() - 2); // 根据类名获取Class对象 Class clazz = Class.forName(className); Method method = null; Class tmp = clazz; // 判断次方法是否存在 while (tmp != null) { try { // 若存在,获取方法对象,以防是私有方法,使用getDeclaredMethod方法获取 method = tmp.getDeclaredMethod(methodName); break; } catch (NoSuchMethodException e) { // 若不存在,在父类中获取此方法 tmp = tmp.getSuperclass(); } } Object object = clazz.newInstance(); // 根据Class对象创建对象 // 突破私有方法的禁锢性 method.setAccessible(true); return method.invoke(object); } public static void main(String[] args) { try { Object object = methodInvoker("java.lang.String.length()"); System.out.println(object); } catch (Exception e) { e.printStackTrace(); } } }动态代理:客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。从而实现一个客户代理对象可以完成多个业务的代理。
动态的代理实例:一个代理可以完成房屋出租、售票等.....业务
// 动态的代理实例,一个代理可以完成房屋出租、售票等.....业务 package com.aguigu.javase.reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 创建一个HouseRent接口,其中有Rent方法(房屋出租) interface HouseRent { public void rent(); } // 创建一个FangDong类,实现HouseRent接口的Rent方法(房屋出租) class FangDong implements HouseRent { @Override public void rent() { System.out.println("婚房, 请爱护"); } } // 创建一个TrainTicket接口,其中有buy方法(售票) interface TrainTicket { public void buy(); } // 创建一个BeijingNan类,实现TrainTicket接口的buy方法(售票) class BeiJingNan implements TrainTicket { @Override public void buy() { System.out.println("您请稍等, 正在出票..."); for (int i = 0; i < 10000000; i++) { int j = i * i; } } } // 创建一个MyInvocationHandler类实现InvocationHandler接口,将被代理对象作为属性,实现对象的关联,并提供get,set方法 class MyInvocationHandler implements InvocationHandler { private Object target; // 被代理对象 public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } // method方法调用必须需要一个真的被代理对象 @Override public Object invoke(Object proxy, Method method, Object[] args) // 第1个是代理对象, 第2个是代理方法, 第3个是方法需要实参 throws Throwable { // 调用对象.getClass方法获取对的类模板,方法名的getName方法获取方法名 System.out.println("动态代理代理对象[" + proxy.getClass() + "],方法[" + method.getName() + "]调用前"); long time1 = System.currentTimeMillis(); // 执行被代理对象的方法,并返回被代理对象类型的对象 Object object = method.invoke(target, args); long time2 = System.currentTimeMillis(); System.out.println("动态代理方法[" + method.getName() + "]执行完毕 , 共用了" + (time2 - time1) + "毫秒"); return object; } } public class ProxyTest { public static void main(String[] args) { MyInvocationHandler h = new MyInvocationHandler(); FangDong fd = new FangDong(); h.setTarget(fd);//设置被代理对象 HouseRent hRent = (HouseRent)Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), // 第一个参数是类加载器类加载器 fd.getClass().getInterfaces(), // 代理类中的所有接口 h); // 第三个参数是一个方法调用处理器(包含了对象原始对象的方法的进一步处理) hRent.rent(); // 重复利用方法调用处理器 h.setTarget(new BeiJingNan()); // 只需要改变被代理对象即可 TrainTicket tt = (TrainTicket)Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), new Class[]{TrainTicket.class}, h); tt.buy(); } }