14

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 メソッドにリスナーを追加する方法を探しています。

4

3 に答える 3

13

いいえ、あなたの例のようにはできません。

あなたの例では、Java コンパイラは 2 つの別個のクラスを作成します。

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();
于 2012-12-08T19:48:06.063 に答える
2

インターフェイス型のオブジェクトを返す場合は、Proxy.newProxyInstanceメソッド呼び出しをオブジェクトに動的に送信するインターフェイスのインスタンスを取得するために使用できInvocationHandlerます。このオブジェクトを記述して、必要なカスタム動作を行うことができます。

于 2012-12-08T18:25:32.503 に答える
0

いいえ、あなたが求めているのはランタイム コンパイルのようなものです。不可能ではありませんが、リフレクション API が提供するものではないことは確かです。

于 2012-12-08T17:31:11.720 に答える