13

コンパイル時にクラスを拡張する機能がありますが、すでにインスタンス化されているスーパークラスのインスタンスを使用して、実行時にこのサブクラスのインスタンスを作成できる必要があります。

スーパークラスコンストラクターはサブクラスコンストラクターの前にすでに呼び出されているため、これは理論的には可能です。

サブクラスへのインスタンス化を変更したり、元のインスタンス化を中断したりするのに十分なプログラムへのアクセス権がありません。

ユースケース:クラスXのインスタンスの既存の配列があります。私のコードは後にロードされます。インスタンスXの1つのメソッドの1つを、ロードされたサブクラスY extends Xでオーバーライドする必要があります。親プログラムはその配列を介してのみオブジェクトにアクセスするため、その配列要素をYインスタンスに置き換える必要がありますが、元々その配列にインスタンス化されたかのように動作します。スーパークラスインスタンスと転送呼び出しを単に囲むことはできません。また、スーパークラスを再インスタンス化することには困難な問題があります。

それがもっと明確になることを願っています。

4

4 に答える 4

6

あなたがやろうとしていることを繰り返すために..

JVM内には、ClassAのインスタンスが存在します。ClassAのクラス階層を動的に変更して、ClassAから派生したClassBと呼ばれる新しいクラスが存在するようにします。次に、ClassBのインスタンスをインスタンス化しますが、そのサブクラスの実装をClassAの既存のインスタンスの実装にします。メモリ交換のようなもの。

http://www.jboss.org/javassistを調べることをお勧めします。あなたがする必要があるのは、ClassLoaderを置き換え、次にClassAがロードされているときを判別し、次にインスタンス化することです。次に、ClassBを作成し、代わりにそれを返す必要があります。

アップデート

もう少し研究した後でも、あなたがやりたいことができる可能性があります。EclipseのようなIDEは、デバッグ中にHotSwapメソッドの実装をサポートします。InstrumentationAPIを使用します。

http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/

メソッド本体を置き換えることはできますが、メソッド自体を追加または削除することはできません。したがって、タイプを新しいタイプに変更することはできませんが、メソッドの実装を新しい実装に完全に置き換えることができます。

于 2012-04-06T16:15:51.833 に答える
3

cglibの使用をお勧めします:

cglibは、強力で高性能かつ高品質のコード生成ライブラリです。JAVAクラスを拡張し、実行時にインターフェイスを実装するために使用されます。

ここにいくつかの例があります: https ://github.com/cglib/cglib/wiki

于 2012-04-06T16:17:13.160 に答える
2

Java Proxies を見たことがありますか?

Javadoc のスニペットを次に示します。

「動的プロキシ クラス (以下、単にプロキシ クラスと呼ぶ) は、クラスの作成時に実行時に指定されたインターフェイスのリストを実装するクラスです」

于 2012-04-06T16:12:57.180 に答える
2

それが解決策かどうかはわかりませんが、もしあれば

public static Foo foo = new Foo();

それを Foo を拡張する Bar に置き換えて、Bar を Foo のラッパーにし、リフレクションを使用して foo が Bar インスタンスを指すようにします。

public class Foo extends Bar {
  private bar; 
  public Foo(Bar oldInstance) {
     this.bar = oldInstance;
  }
}

// exception handling ommitted
public static void onStartup() {
   Class fooRefClass = FooRef.class;
   Field fooRef = fooRefClass.getDeclaredField("foo");

   Foo foo = (Foo)fooRef.get(null);
   Bar bar = new Bar(foo);
   fooRef.set(null, bar);

}

言われたように、これがあなたの場合に可能かどうかはわかりません。

于 2012-04-06T17:34:32.160 に答える