如何使用 InvocationHandler#invoke(...) 方法的 `proxy` 参数?

How to use `proxy` parameter of InvocationHandler#invoke(...) method?

我有以下代码:

public class Test {
    public static void main(String[] args) {
        InvocationHandler ih = new MyHandler();
        ClassLoader cl = Test.class.getClassLoader();
        Class[] mapClass = {Map.class};
        
        ((Map)Proxy.newProxyInstance(cl,mapClass,ih)).put("hello", 11);
        
        ((Map)Proxy.newProxyInstance(cl,mapClass,ih)).put("hi", 55);
    }
}

class MyHandler implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("\nInvoked method `" + method.getName() + "` args: " + Arrays.toString(args));

        System.out.println(proxy.getClass());
        //how to use proxy parameter? and what purposes it can be used?
        
        return 42;
    }
}

输出:

Invoked method `put` args: [hello, 11]
class com.sun.proxy.$Proxy0

Invoked method `put` args: [hi, 55]
class com.sun.proxy.$Proxy0

请告诉我:
如何使用 proxy 参数?非本机方法调用 yield Whosebug 错误。
它可以用于什么目的?

您可以像这样实现 equalshashCode(与 Object 实现具有相同的语义):

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 ProxyEg {
    interface Foo {
    }

    public static void main(String[] args) {
        List<Foo> foos = new ArrayList<>();
        InvocationHandler ih = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getName().equals("equals")) {
                    return proxy == args[0];
                } else if (method.getName().equals("hashCode")) {
                    return System.identityHashCode(proxy);
                }
                return null;
            }
        };
        for (int i = 0; i < 2; i++) {
            foos.add((Foo)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[] {Foo.class}, ih));
        }

        // with an 'empty' InvocationHandler all of these lines will throw UnsupportedOperationException
        System.out.println(foos.get(0).equals(foos.get(1)));
        System.out.println(foos.get(0).equals(foos.get(0)));
        System.out.println(foos.get(0).hashCode());
        System.out.println(foos.get(1).hashCode());
    }
}