Từ javadocs API cho java.lang.reflect.InvocationHandler:
InvocationHandler là giao diện được thực hiện bởi bộ xử lý gọi của một trường hợp proxy.
Proxy động triển khai giao diện, nhưng sử dụng trình xử lý (OriginalClass) để cung cấp triển khai cơ sở của phương pháp.
Để trả lời câu hỏi của bạn:
- Trình biên dịch sẽ cho phép bạn chọn vào vai miễn là nó không có đủ thông tin để chắc chắn rằng các diễn viên không thể thành công. Các hành vi thời gian chạy của đúc và instanceof thử nghiệm cho proxy động được mô tả trong javadoc cho java.lang.reflect.Proxy. Các test và instanceof sẽ thành công nếu được sử dụng với các giao diện, nhưng không thành công nếu được sử dụng với các lớp.
- Bạn không thể truy cập bất kỳ thuộc tính nào bằng proxy động vì nó thực hiện giao diện, nó không mở rộng lớp trình xử lý.
- Bạn không thể truy cập bất kỳ phương thức nào không được khai báo trong giao diện bằng proxy động bởi vì nó triển khai giao diện, nó không mở rộng lớp trình xử lý.
Bên trong việc triển khai proxy động (ví dụ: khi triển khai lệnh gọi (...)) bạn có thể truy cập các thành viên của trình xử lý bằng cách sử dụng sự phản chiếu.
Dưới đây là một số mã kiểm tra mà tôi sử dụng để kiểm tra câu trả lời của tôi:
// package ...;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.Assert;
import org.junit.Test;
public class TestDynamicProxy
{
@Test
public void testCast() throws Exception {
Foo foo = (Foo) TestProxy.newInstance(new FooImpl());
foo.bar(null);
System.out.println("Class: " + foo.getClass());
System.out.println("Interfaces: " + foo.getClass().getInterfaces());
Assert.assertNotNull(foo);
Assert.assertTrue(foo instanceof Foo);
Assert.assertFalse(foo instanceof FooImpl);
}
}
interface Foo
{
Object bar(Object obj) throws Exception;
}
class FooImpl implements Foo
{
public Object bar(Object obj) throws Exception {
return null;
}
}
class TestProxy implements java.lang.reflect.InvocationHandler
{
private final Object obj;
public static Object newInstance(Object obj) {
return java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new TestProxy(obj));
}
private TestProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
result = m.invoke(obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
article này có rất nhiều thông tin hữu ích và mã ví dụ.
Bạn có chắc chắn rằng việc truyền proxy của mình tới OriginalClass hoạt động không? Theo hiểu biết của tôi nếu bạn đã tạo proxy cho OriginalInterface, bạn không thể truyền tới OriginalClass –