Menurut dokumentasi :
[
java.lang.reflect.
]Proxy
menyediakan metode statis untuk membuat kelas dan instance proxy dinamis, dan ini juga merupakan superclass dari semua kelas proxy dinamis yang dibuat dengan metode tersebut.
The newProxyMethod
Metode (bertanggung jawab untuk menghasilkan proxy dinamis) memiliki tanda tangan berikut:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Sayangnya, hal ini mencegah seseorang menghasilkan proxy dinamis yang memperluas kelas abstrak tertentu (daripada mengimplementasikan antarmuka tertentu). Ini masuk akal, mengingat java.lang.reflect.Proxy
adalah "kelas super dari semua proxy dinamis", sehingga mencegah kelas lain menjadi kelas super tersebut.
Oleh karena itu, apakah ada alternatif java.lang.reflect.Proxy
yang dapat menghasilkan proxy dinamis yang mewarisi dari kelas abstrak tertentu, mengarahkan semua panggilan ke metode abstrak ke penangan permintaan?
Misalnya, saya memiliki kelas abstrak Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
Apakah ada kelas yang mengizinkan saya melakukan hal berikut?
Dog dog = SomeOtherProxy.newProxyInstance(classLoader, Dog.class, h);
dog.fetch(); // Will be handled by the invocation handler
dog.bark(); // Will NOT be handled by the invocation handler
sumber
proxyFactory.setHandler()
sudah ditinggalkan. Silakan gunakanproxy.setHandler
.Apa yang dapat Anda lakukan dalam kasus seperti itu adalah memiliki penangan proxy yang akan mengarahkan panggilan ke metode yang ada dari kelas abstrak Anda.
Anda tentu saja harus mengkodekannya, namun ini cukup sederhana. Untuk membuat Proxy Anda, Anda harus memberinya
InvocationHandler
. Anda kemudian hanya perlu memeriksa jenis metode dalaminvoke(..)
metode penangan permintaan Anda. Namun berhati-hatilah: Anda harus memeriksa jenis metode terhadap objek pokok yang terkait dengan penangan Anda, dan bukan terhadap jenis yang dideklarasikan dari kelas abstrak Anda.Jika saya mengambil contoh kelas anjing Anda, metode pemanggilan penangan doa Anda mungkin terlihat seperti ini (dengan subkelas anjing terkait yang ada disebut .. yah ...
dog
)public void invoke(Object proxy, Method method, Object[] args) { if(!Modifier.isAbstract(method.getModifiers())) { method.invoke(dog, args); // with the correct exception handling } else { // what can we do with abstract methods ? } }
Namun, ada sesuatu yang membuat saya bertanya-tanya: Saya telah berbicara tentang suatu
dog
objek. Namun, karena kelas Dog bersifat abstrak, Anda tidak dapat membuat instance, jadi Anda memiliki subkelas yang sudah ada. Selain itu, seperti yang ditunjukkan oleh pemeriksaan kode sumber Proxy yang cermat, Anda mungkin menemukan (di Proxy.java:362) bahwa tidak mungkin membuat Proxy untuk objek Kelas yang tidak mewakili antarmuka).Jadi, terlepas dari kenyataan , apa yang ingin Anda lakukan adalah mungkin.
sumber
Dog
(misalnya, saya tidak secara eksplisit menulisPoodle
kelas yang mengimplementasikanfetch()
). Oleh karena itu, tidak adadog
variabel untuk memanggil metode di atas ... Maaf jika saya bingung, saya harus memikirkan ini sedikit lagi.java.lang.reflect.Proxy
) tersedia yang melakukan apa yang saya butuhkan.