[英]How can I override methods in Java when I create an Object via reflection?
在Java中 ,是否可以覆蓋使用reflection
創建的類中的方法? 例如,假設我有以下課程:
public class MyObject
{
public String foo, bar;
public MyObject(String foo)
{
this.foo = foo;
this.bar = foo + "bar";
}
public void setBar(String bar)
{
this.bar = bar;
}
}
在一個類中,我想直接創建它並覆蓋其setBar
方法,如下所示:
MyObject obj = new MyObject("something")
{
@Override
public void setBar(String bar)
{
this.bar = this.foo;
}
};
有沒有辦法使用反射以相同的方式覆蓋方法? 也許是這樣的? :
Class<?> _class = Class.forName("com.example.MyObject");
Constructor<?> _constructor = _class.getConstructor(new Class<?>[]{String.class});
Method m = _class.getMethod("setBar", new Class<?>[]{String.class});
Object obj = _constructor.newInstance("Foo String")
{
m = new Method(new Class<?>[]{String.class})
{
System.out.println("Foobar");
}
};
如果沒有,是否有其他方法可以做到這一點,或外部庫可以幫助? 我正在尋找將偵聽器添加到setter方法以便更改綁定值的方法。
不,這不可能以你的例子的方式。
在您的示例中,Java編譯器將創建兩個單獨的類:
MyObject.class
MyObject$1.class
后者是具有重寫方法的那個。 在這種情況下,它是一個匿名內部類 (請參閱Java教程文檔 )
但是有更復雜的解決方案涉及字節碼編織庫。 諸如cglib,asm,javassist等庫為您提供了在運行時動態創建新類並加載它們的工具。
Javassist有一個關於如何在運行時向類添加方法的教程。 應該可以調整它來添加/覆蓋方法,如下所示:
CtClass origClazz = ClassPool.getDefault().get("org.example.MyObject");
CtClass subClass = ClassPool.getDefault().makeClass(cls.getName() + "New", origClazz);
CtMethod m = CtNewMethod.make(
"public void setBar(String bar) { this.bar = bar; }",
subClass );
subClass .addMethod(m);
Class clazz = cc.toClass();
如果要返回接口類型的對象,則可以使用Proxy.newProxyInstance
來獲取接口的實例,該接口將動態發送方法調用發送到InvocationHandler
對象,您可以編寫該對象以執行所需的任何自定義行為。
不,你要求的是運行時編譯。 雖然並非不可能,但它肯定不是反射API提供的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.