简体   繁体   English

了解java.lang.reflect.InvocationHandler的invoke方法的“代理”参数

[英]Understanding “proxy” arguments of the invoke method of java.lang.reflect.InvocationHandler

I would like to understand the purpose of the proxy argument of the invoke method of java.lang.reflect.InvocationHandler . 我想了解java.lang.reflect.InvocationHandlerinvoke方法的proxy参数的用途。

  • How and when should it be used? 应如何以及何时使用?
  • What is its runtime-type? 它的运行时类型是什么?
  • Why not use this instead? 为什么不使用this呢?

There's in fact little you can do with the actual proxy. 实际上,使用实际代理几乎无济于事。 Nevertheless it's part of the invocation context, and you can use it to gain information on the proxy using reflection, or use it in subsequent calls (when calling another method with that proxy, or as a result. 尽管如此,它还是调用上下文的一部分,您可以使用它通过反射来获取有关代理的信息,或者在后续调用中使用该代理(当使用该代理调用另一个方法时,或者作为结果)。

Example: an acccount class, which allows to deposit money, whose deposit() method returns the instance again to allow method chaining: 示例:一个允许存款的帐户类,其deposit()方法再次返回该实例以允许方法链接:

private interface Account {
    public Account deposit (double value);
    public double getBalance ();
}

Handler: 处理程序:

private class ExampleInvocationHandler implements InvocationHandler {

    private double balance;

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

        // simplified method checks, would need to check the parameter count and types too
        if ("deposit".equals(method.getName())) {
            Double value = (Double) args[0];
            System.out.println("deposit: " + value);
            balance += value;
            return proxy; // here we use the proxy to return 'this'
        }
        if ("getBalance".equals(method.getName())) {
            return balance;
        }
        return null;
    }
}

And an example of its usage: 以及其用法示例:

Account account = (Account) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[] {Account.class, Serializable.class},
    new ExampleInvocationHandler());

// method chaining for the win!
account.deposit(5000).deposit(4000).deposit(-2500);
System.out.println("Balance: " + account.getBalance());

As for your second question: the runtime type can be evaluated using reflection: 至于您的第二个问题:可以使用反射来评估运行时类型:

for (Class<?> interfaceType : account.getClass().getInterfaces()) {
    System.out.println("- " + interfaceType);
}

And your third question: ' this ' would refer to the invocation handler itself, not the proxy. 第三个问题是:“ this ”是指调用处理程序本身,而不是代理。

To complement Peter's answer. 补充彼得的回答。 I added the following line regarding the runtime-type of the proxy: 我添加了以下有关代理的运行时类型的行:

System.out.println("accountGetClass() : " + account.getClass());

Which outputs: 哪个输出:

accountGetClass() : class com.sun.proxy.$Proxy0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 调用的java.lang.reflect.InvocationHandler的方法参数列表中的“代理”对象代表什么? - What does “proxy” object from invoke's method parameters list of java.lang.reflect.InvocationHandler represent? java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler - java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler 替换java.lang.reflect.Proxy中的InvocationHandler - Replace InvocationHandler in java.lang.reflect.Proxy 将return对象替换为java.lang.reflect.InvocationHandler不起作用。 如何在代理呼叫中完全替换返回对象? - Substituting of return object for java.lang.reflect.InvocationHandler is not working. How to fully substitute the return object in proxied call? 为什么InvocationHandler中的方法invoke()有一个参数Object proxy? - why does the method invoke() in InvocationHandler have an parameter Object proxy? 使用对象数组调用Scala中的java.lang.reflect.Method - Invoke java.lang.reflect.Method in Scala with Object array java.lang.reflect.Method invoke()参数类型不匹配异常 - java.lang.reflect.Method invoke() argument Type mismatch exception 应用程序启动方法 java.lang.reflect.InvocationTargetException 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 中的异常 - Exception in Application start method java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 为什么jdk动态代理在调试每一步模式时调用InvocationHandler.invoke“toString”方法 - Why jdk dynamic proxy invoke InvocationHandler.invoke “toString” method when debug every step over mode 使用InvocationHandler在代理类中调用NoClassDefFound并调用 - NoClassDefFound in proxy class using InvocationHandler and invoke
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM