您的位置:首页 > 编程语言 > Java开发

java学习之路 之 反射机制综合练习题、动态代理实例

2016-09-04 16:43 976 查看
 在上一篇博文中我们已经进行了反射机制的习题练习,这里我们在做一个考察比较全面的练习,如下:

写一个类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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: