黑马程序员技术交流社区
标题:
请高手多一点解释
[打印本页]
作者:
陆旭东
时间:
2013-4-4 22:15
标题:
请高手多一点解释
写一个ArrayList类的代理,实现和ArrayList中完全相同的功能,并可以计算每个方法运行的时间
作者:
lucy198921
时间:
2013-4-4 22:27
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ListProxy {
public static void main(String[] args) throws Exception {
List<String> list = newList(String.class);
list.add("abc");
System.out.println(list);
}
@SuppressWarnings("unchecked")
public static <T> List<T> newList(Class<T> elementType) {
return (List<T>)Proxy.newProxyInstance(List.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler() {
private List<T> realList = new ArrayList<T>();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long start = System.nanoTime();
Object ret = method.invoke(realList, args);
long end = System.nanoTime();
System.out.println("调用" + method.getName() + "耗时:" + (end - start) + "纳秒");
return ret;
}
});
}
}
作者:
陆旭东
时间:
2013-4-4 22:58
能帮我解释下下面这段代码的意思吗?谢谢
作者:
王川
时间:
2013-4-4 23:39
public class ProxyTest{
public static void main(String[] args) {
List myProxy3 = (List) Proxy.newProxyInstance(
ArrayList.class.getClassLoader(), //第一个参数(类加载器)
new Class[]{List.class}, //第二个参数(实现的多个接口组成的数组)
new InvocationHandler(){
ArrayList target = new ArrayList();//为动态类指定一个目标
@Override
/*调用的代理对象 proxy, 对象的方法method, 方法的参数args*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long startTime = System.currentTimeMillis();
//用传递进来的方法和参数在target对象上执行
Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();
long invokeTime = endTime - startTime;
System.out.println(invokeTime);
return retVal;
}
}//第三个参数(匿名的内部类,实现了接口InvocationHandler)
);
/*每调用一次myProxy3的方法,都要去找InvocationHandler对象的invoke方法*/
myProxy3.add("zhangsan");
myProxy3.add("lisi");
myProxy3.add("wangwu");
}
}
复制代码
注释差不多说清楚了,这里是试验的add方法的执行时间,其他方法类似
作者:
刘焕新
时间:
2013-4-5 00:28
我也写了一个,和楼上的差不多,就是注释多写了些,希望能帮到你。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ProxyTest {
public static void main(String[] args) {
//定义一个List对象,我称它为原始对象,即:将被代理的实例对象
List object = new ArrayList();
//获取动态代理对象
List proxyObject = (List)getProxyObject(object);
//以代理对象来执行原始对象的方法:
proxyObject.add("hello");
int size = proxyObject.size();
System.out.println(size);
}
//通过动态代理的方式获取一个代理对象,此代理对象在保留了原对象要执行的方法的基础上,还会执行计时操作:
public static Object getProxyObject(final Object object) {
Object proxyObject = (Object)Proxy.newProxyInstance
(
object.getClass().getClassLoader(), //原始对象的类加载器
object.getClass().getInterfaces(), //原始对象的接口们
//创建了一个实现InvocationHandler接口的匿名类的实例:
new InvocationHandler()
{
//实现InvocationHandler接口的invoke方法:
@Override
public Object invoke(Object o, Method m, Object[] args) throws Exception
{
//目标方法执行前的时间记录
long start = System.nanoTime();
//执行原始对象的目标方法:(此处传入的是原始对象,以及目标方法所需的参数)
Object retVal = m.invoke(object, args);
//目标方法执行后的时间记录:
long end = System.nanoTime();
System.out.println("原始对象的目标方法名为:" + m.getName() + ",执行耗时"+(end-start)+"纳秒!");
//返回目标方法的返回值:
return retVal;
}
}
);
return proxyObject;
}
}
复制代码
作者:
刘印12
时间:
2013-4-5 01:36
本帖最后由 刘印12 于 2013-4-5 01:47 编辑
看我这个解释 你最好复制到写java代码的应用软件上,能解释的我都在上面标示了
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
public class ListProxy {
public static void main(String[] args) throws Exception {//相信主函数里面的东西你是能看的懂的
List<String> list = newList(String.class);
list.add("abc");
System.out.println(list);
}
@SuppressWarnings("unchecked")//这句话是处理安全问题的你不用管
public static <T> List<T> newList(Class<T> elementType) {//创建ArrayList的代理对象newList。。。。。
return (List<T>)Proxy.newProxyInstance(List.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler() {
/*
这个地方用到了Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)的这个方法
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
参数: loader - 定义代理类的类加载器 =======
List.class.getClassLoader() 返回该类的类加载器。
interfaces - 代理类要实现的接口列表===== new Class[]{List.class},
指派方法调用的调用处理程序//它是一个接口要定义一个方法覆盖它的invoke()方法
*/
private List<T> realList = new ArrayList<T>();//创建ArrayList的对象
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long start = System.nanoTime();//System.nanoTime()返回最准确的可用系统计时器的当前值(Long类型的),
//以毫微秒为单位。。。。。这句就是返回代理对象开始调用方法时所用的时间
Object ret = method.invoke(realList, args);
/*
method.invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
参数: obj - 从中调用底层方法的对象
args - 用于方法调用的参数
返回: 使用参数 args 在 obj 上指派该对象所表示方法的结果
*/
long end = System.nanoTime();//这句返回的是代理对象结束运行时总共的用时
System.out.println("调用" + method.getName() + "耗时:" + (end - start) + "纳秒");
return ret;
}
});
}
}
作者:
陈丽莉
时间:
2013-4-6 00:44
追问或结贴~ 记得及时处理自己的帖子~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2