, . , . , , setShareholders Person, , , , , , , , , .
, . "" E, " [] , Person". - E "" / Person ( , E).
: OP , :
:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy {
public static class DelegatingInvocationHandler
implements InvocationHandler {
private final Object delegate;
public DelegatingInvocationHandler(final Object delegate) {
this.delegate = delegate;
}
@Override
public Object invoke(final Object proxy, final Method m,
final Object[] args) throws Throwable {
Object result;
try {
result = m.invoke(delegate, args);
} catch (final InvocationTargetException e) {
throw e.getTargetException();
} catch (final Exception e) {
throw new RuntimeException("unexpected invocation exception: "
+ e.getMessage());
}
return result;
}
}
public static <T> T createSelectiveProxy(final T delegate,
final Class<T> requiredInterface,
final Class<?>... moreInterfaces) {
if (delegate == null) {
throw new IllegalArgumentException(
"The delegate object cannot be null");
}
return createProxy(new DelegatingInvocationHandler(delegate),
requiredInterface, moreInterfaces);
}
@SuppressWarnings("unchecked")
public static <T> T createProxy(final InvocationHandler invocationHandler,
final Class<T> requiredInterface,
final Class<?>... moreInterfaces) {
if (invocationHandler == null) {
throw new IllegalArgumentException(
"The invocation handler cannot be null");
}
final int size = (moreInterfaces != null ? moreInterfaces.length : 0);
final Class<?>[] interfaces = new Class<?>[size + 1];
interfaces[0] = requiredInterface;
System.arraycopy(moreInterfaces, 0, interfaces, 1, moreInterfaces.length);
return (T) Proxy.newProxyInstance(invocationHandler.getClass()
.getClassLoader(), interfaces, invocationHandler);
}
}
:
public class DynamicProxyDemo {
private interface A {
void methodA();
}
private interface B {
void methodB();
}
private static class Foo implements A, B {
public void methodA() {
System.out.println("A");
}
public void methodB() {
System.out.println("B");
}
}
private DynamicProxyDemo() {}
public static void main(final String[] args) {
final Foo foo = new Foo();
final A a = DynamicProxy.createSelectiveProxy(foo, A.class);
final B b = DynamicProxy.createSelectiveProxy(foo, B.class);
final A ab = DynamicProxy.createSelectiveProxy(foo, A.class, B.class);
System.out.println("\n *** Call a method A.methodA() on proxy 'a'");
a.methodA();
try {
System.out.println("\n *** Call a method B.methodB() on proxy 'a' (throws exception)");
((B) a).methodB();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
System.out.println("\n *** Call a method B.methodB() on proxy 'b'");
b.methodB();
try {
System.out.println("\n *** Call a method A.methodA() on proxy 'b' (throws exception)");
((A) b).methodA();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
System.out.println("\n *** Call a method A.methodA() on proxy 'ab'");
ab.methodA();
System.out.println("\n *** Call a method B.methodB() on proxy 'ab'");
((B) ab).methodB();
try {
System.out.println("\n *** Call a method 'A' of class 'Foo' on proxy 'a' (throws exception)");
((Foo) a).methodA();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
try {
System.out.println("\n *** Call a method 'B' of class 'Foo' on proxy 'b' (throws exception)");
((Foo) b).methodB();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
try {
System.out.println("\n *** Call a method B.methodB() on proxy 'a' (throws exception)");
((B) a).methodB();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
try {
System.out.println("\n *** Call a method A.methodA() on proxy 'b' (throws exception)");
((A) b).methodA();
} catch (final Exception ex) {
ex.printStackTrace(System.out);
}
}
}
Run:
*** Call a method A.methodA() on proxy 'a'
A
*** Call a method B.methodB() on proxy 'a' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy0 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$B
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:49)
*** Call a method B.methodB() on proxy 'b'
B
*** Call a method A.methodA() on proxy 'b' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy1 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$A
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:59)
*** Call a method A.methodA() on proxy 'ab'
A
*** Call a method B.methodB() on proxy 'ab'
B
*** Call a method 'A' of class 'Foo' on proxy 'a' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy0 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$Foo
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:73)
*** Call a method 'B' of class 'Foo' on proxy 'b' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy1 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$Foo
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:81)
*** Call a method B.methodB() on proxy 'a' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy0 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$B
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:89)
*** Call a method A.methodA() on proxy 'b' (throws exception)
java.lang.ClassCastException: net.bertfernandez.reflection.$Proxy1 cannot be cast to net.bertfernandez.reflection.DynamicProxyDemo$A
at net.bertfernandez.reflection.DynamicProxyDemo.main(DynamicProxyDemo.java:97)