0

A service from external API which I am not allowed to modify returns me

  MyClass instance = ServiceUtil.getThing();

I would like to extend this returned class and Add/Override a method but leave intacts the others, say 150 methods.

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

Is there any way to force this "casting" from the returned MyClass instance to my newly particular subtype??

NOTE: Please, not suggest the approach of making a constructor, passing the original object and having to copy and implement the 150 methods to call the wrapped object

4

3 回答 3

7

If MyClass is an interface look at java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler.

You can implement a dynamic proxy that always does the same. It is, always pass control to your original implementation... except when method X is invoked.

Something like:

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);
  }
}

Note: you must create this proxy implementation anyway:

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

I hope I get you right: you have a

MyClass instance = ServiceUtil.getThing();

but want something like

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

(which obviously doesn't work, even though MyWrapperClass extends MyClass).

The solution is to create a new instance of MyWrapperClass based on the MyClass and, sorry to say that, using the constructor is a good approach (public MyWrapperClass(MyClass myClass)).

于 2012-08-16T09:44:47.573 回答
1

Please, not suggest the approach of making a constructor, passing the original object and having to copy and implement the 150 methods to call the wrapped object

You mean to say that "decoration" is not an option you would like to look at right?

But decoration will be a problem to you if MyClass is an interface type where you have to define those 150 odd methods, delegating the 149 method calls onto the decorated and overriding that one method.

If MyClass is a class type, then you don't need to write those 149 methods, right? or Did I get you completely wrong?

于 2012-08-16T09:26:05.700 回答