1

I have following code:

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

Output:

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

Please tell me:
how can I use the proxy parameter? Non native methods calls yield stackoverflow error.
for what purposes it can be used?

3
  • The only use I can think of for them is implementing equals and hashCode Commented Aug 27, 2021 at 6:51
  • @tgdavies calling equals and hashcode methods on the proxy parameter gives java.lang.StackOverflowError. Commented Aug 27, 2021 at 7:02
  • I suppose the reason for the stackOverflow is : InvocationHandler: "When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.", so calling a method on the proxy from with the invoke-method invokes it again. Commented Aug 27, 2021 at 7:20

1 Answer 1

1

You can implement equals and hashCode (with the same semantics as the Object implementations) like this:

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()); } } 
Sign up to request clarification or add additional context in comments.

1 Comment

Thx! I think the instanceof operator can also be used, if we want to use same handler for proxies of various types.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.