论坛首页 入门技术论坛

Java动态代理的设计是否有缺陷??

浏览 14609 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-04-24  
唉 java.lang.reflect 中的 我就没熟的 惭愧啊
0 请登录后投票
   发表时间:2010-04-24   最后修改:2010-04-24
引用

我的疑问:
1、在InvocationHandler中的invoke方法中的那个参数 proxy
不能调用toString、hashCode方法;
虽然可以转型为 实体类,但是 不能 在 method.invoke(obj,args)中使用。
不知道这个参数有什么用???
2、既然proxy不知道怎么用,于是,就自己添加个 setTarget(Object  target)方法,注入具体的对象。



public interface InvocationHandler{
    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

此invoke将拦截所有代理的方法调用,包含了继承自Object的方法

 

1. 可以调用toString()和hashCode()方法的,需要自己在invoke中进行处理如:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

    if (method.getName().equals('toString')) {....}

    else if (method.getName().equals('hasCode')) {....}

}

实际上你任何执行此方法都是错误的:method.invoke(proxy, argus),注意这里的proxy本身就是代理,如果代理执行invoke,那么还是会被InvocationHandler.invoke拦截的,也就是任何method.invoke(proxy,argus)依然还是对InvocationHandler.invoke的调用,恭喜从此进入死循环了

 

2 代理可以是对真实存在的对象进行代理,

所以你需要方法setTarget(),更好的做法是在构造InvocationHandler时输入,如:

new MyInvocationHandler(target);

你可以使用

Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

    if (method.getName().equals('toString') || method.getName().equals('hasCode')) {return method.inoke(target, args);}

}

3 代理也可以是一个虚幻的对象实例,只是这个实例的所有方法实现在InvocationHandler.invoke 中实现的

 

 

1 请登录后投票
   发表时间:2010-04-24  
lanxiangbo 写道
看的有点迷糊。。。
1、既然你proxy里有类型信息了,你还有什么干不了得呢?为什么还要setTarget
2、既然proxy只是提供类型信息,那么他可能只是RealInterface而不是RealObject?那你去掉newInstance()难道不应该报错。。而且你为什么会要去newInstance()


我本以为 通过proxy可以得到目标对象的构造方法。但是这样是不正确的。

0 请登录后投票
   发表时间:2010-04-24  
teclogid 写道
谁说target是必须的?
动态代理只是为一个接口产生一个动态的实例,这个实例可以调用其他对象的方法,如你所说的target,也可以不调用。


你可以试试,InvocationHandler的proxy参数。

另外,传入的target是可以用的。 请运行下我的代码。
0 请登录后投票
   发表时间:2010-04-24  
skzr.org 写道


public interface InvocationHandler{
    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

此invoke将拦截所有代理的方法调用,包含了继承自Object的方法

 

1. 可以调用toString()和hashCode()方法的,需要自己在invoke中进行处理如:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

    if (method.getName().equals('toString')) {....}

    else if (method.getName().equals('hasCode')) {....}

}

实际上你任何执行此方法都是错误的:method.invoke(proxy, argus),注意这里的proxy本身就是代理,如果代理执行invoke,那么还是会被InvocationHandler.invoke拦截的,也就是任何method.invoke(proxy,argus)依然还是对InvocationHandler.invoke的调用,恭喜从此进入死循环了

 

2 代理可以是对真实存在的对象进行代理,

所以你需要方法setTarget(),更好的做法是在构造InvocationHandler时输入,如:

new MyInvocationHandler(target);

你可以使用

Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

    if (method.getName().equals('toString') || method.getName().equals('hasCode')) {return method.inoke(target, args);}

}

3 代理也可以是一个虚幻的对象实例,只是这个实例的所有方法实现在InvocationHandler.invoke 中实现的

 

 

 

你说的很对,很受教导!谢谢!!

0 请登录后投票
   发表时间:2010-04-24  
学习了,之前也有类似的疑问,现在弄清楚了
0 请登录后投票
   发表时间:2010-04-25  
愿大家的生活更美好
0 请登录后投票
   发表时间:2010-04-25  

⊙﹏⊙b汗

被搞成“新手帖”。。。。。。。

我觉得,这个问题提的不错。也有人和我有同样的感受,也没有人能解决这个问题,都证明了SUN这个API是有问题的,也证明了我的帖子的正确性啊!!

不知道,为什么要评为“新手帖”。。。。

尊重JavaEye管理员的权威,可能的话,删帖吧。谢谢!!
0 请登录后投票
   发表时间:2010-04-25  
评新手贴的都是那些自以为很牛B却回答不了你这个问题让他们无法装B的傻B人士评的,楼主不要介意。
0 请登录后投票
   发表时间:2010-04-25  
^_^个人感觉这个api没问题呀,如果没有Object proxy这第一个参数,当我们希望在代理方法中访问proxy的时候该怎么办呢?

最简单的场景就像我之前举出的,
public class Hello {
  public Hello doSomething() {
    return this;
  }
}

如果不提供Object proxy这个第一个参数,我们就不容易获得proxy了,手里最多只有一个target可以用。

如果参与讨论的各位大侠有时间,不妨考虑一下这种情况吧。多谢。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics