簡體   English   中英

當我通過反射創建一個Object時,如何覆蓋Java中的方法?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM