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

时间:2014-04-08 07:21:09

标签: java dynamic-proxy

我想了解proxy的{​​{3}}方法的java.lang.reflect.InvocationHandler参数的用途。

  • 应该如何以及何时使用?
  • 它的运行时类型是什么?
  • 为什么不使用this

2 个答案:

答案 0 :(得分:3)

实际上,你可以用实际的代理做很少的事情。然而,它是调用上下文的一部分,您可以使用它来使用反射获取有关代理的信息,或者在后续调用中使用它(当使用该代理调用另一个方法时,或者作为结果。

示例:一个acccount类,允许存钱,其deposit()方法再次返回实例以允许方法链接:

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

处理程序:

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;
    }
}

以及它的用法示例:

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());

关于第二个问题:可以使用反射评估运行时类型:

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

您的第三个问题:&#39; this&#39;会引用调用处理程序本身,而不是代理。

答案 1 :(得分:0)

补充彼得的答案。我添加了关于代理的运行时类型的以下行:

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

哪个输出:

accountGetClass() : class com.sun.proxy.$Proxy0
相关问题