0

変更が許可されていない外部 API からのサービスが返されます

  MyClass instance = ServiceUtil.getThing();

この返されたクラスを拡張し、メソッドを追加/オーバーライドしますが、他のメソッド、たとえば 150 メソッドはそのままにします。

  private class MyWrapperClass extends MyClass(){
      public MyWrapperClass(){super();}
      @Override public String toString(){ return "Blocked toString"; }
  }

返された MyClass インスタンスから新しく特定されたサブタイプにこの「キャスト」を強制する方法はありますか??

注: コンストラクターを作成し、元のオブジェクトを渡し、ラップされたオブジェクトを呼び出すために 150 個のメソッドをコピーして実装する必要があるというアプローチは提案しないでください。

4

3 に答える 3

7

MyClass がインターフェースの場合は、java.lang.reflect.Proxyjava.lang.reflect.InvocationHandlerを見てください。

常に同じことを行う動的プロキシを実装できます。つまり、常に元の実装に制御を渡します... メソッド X が呼び出された場合を除きます。

何かのようなもの:

class MyHandler implements InvocationHandler {
  Object invoke(Object proxy, Method method, Object[] args) {
    if (method is the one you want to change) {
       do whatever
    else
       return method.invoke(originalObject, args);
  }
}

注:とにかく、このプロキシ実装を作成する必要があります。

MyClass original = ServiceUtil.getThing();
MyClass proxy = (MyClass) Proxy.newProxyInstance(
                                          MyClass.class.getClassLoader(), // classloader to use
                                          new Class[] { MyClass.class }, // interfaces to implement
                                          new MyHandler()); // who does the dirty work when methods are invoked
于 2012-08-16T09:30:44.713 に答える
5

私はあなたを正しく理解することを願っています:あなたは

MyClass instance = ServiceUtil.getThing();

しかし、のようなものが欲しい

MyWrapperClass instance = (MyWrapperClass) ServiceUtil.getThing();

MyWrapperClass(拡張しても、明らかに機能しませんMyClass)。

MyWrapperClass解決策は、に基づいての新しいインスタンスを作成することですMyClass。申し訳ありませんが、コンストラクターを使用することは良いアプローチです(public MyWrapperClass(MyClass myClass))。

于 2012-08-16T09:44:47.573 に答える
1

コンストラクターを作成し、元のオブジェクトを渡し、ラップされたオブジェクトを呼び出すために 150 個のメソッドをコピーして実装する必要があるというアプローチを提案しないでください。

「装飾」は見たくない選択肢ということですか?

しかし、MyClass がこれらの 150 の奇妙なメソッドを定義しなければならないインターフェイス タイプである場合、装飾は問題になります。

MyClass がクラス型の場合、149 個のメソッドを記述する必要はありませんよね? または私はあなたを完全に誤解しましたか?

于 2012-08-16T09:26:05.700 に答える