如何使用 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 错误。
它可以用于什么目的?
您可以像这样实现 equals
和 hashCode
(与 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());
}
}
我有以下代码:
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 错误。
它可以用于什么目的?
您可以像这样实现 equals
和 hashCode
(与 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());
}
}