2009-11-05 13 views
6

Javaクラスの実装を置き換える(オーバーライドする)方法はありますか?別の実装(バイト配列として使用可能)によってSystemクラスのローダーによって既に読み込まれていますか?第1のプリント「実装2」として実行時のクラスの実装を置換する(Java)

public class Main { 
    public static void main(String ... args) { 
     Foo foo = new Foo(); 
     foo.print(); 

     ClassLoader cl = ... 

     Foo foo2 = (Foo) cl.newInstance(); 
     foo2.print(); 
    } 
} 

第Fooの印刷物「実装1」のプリント()方法であって、私の疑問を説明するために

は、このコードに従います。 fooの2番目のインスタンスはクラスローダーによってバイトの配列から取り出されます(ファイルに格納することも、ストリームから取得することもできます)。

PS:Fooはクラスではなく、インタフェースを拡張することはできません。つまり、クラス実装を定義する実際のバイト(VM内)がオーバーライドされます。

+0

あなたは本当にこれをしたいと思っていますか?なぜその質問に説明するのがよいでしょう。 –

答えて

0

CGLibはこのようなことを行います。この目的のためにSpringの& Hibernateで使用されています。

0

インストルメンテーションエージェントを実装し、java.lang.instrument.Instrumentation#redefineClasses(...)を使用して、すでにロードされているクラスのバイトコードを置き換えることができます。

4

はい、これは問題ありません。 java.net.URLClassLoaderを使用してください。たとえば、あなたが上書きするファイルが存在するディレクトリであるURLをURLに与えることができます。

編集: 次に、希望のコールはcl.loadClass("Foo").newInstance()です。結果をFooにキャストできませんが、反射を使用してprintメソッドを呼び出すことができます。または、Fooをprintメソッドを定義する再実装しないもののサブクラス(またはインターフェイス実装)にして、それにキャストします。

0

私は、JMXを使用して展開解除クラスと再デプロイクラスを使用します。

関連する問題