Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically delegating all methods of a java class

Say I have a class with many of public methods:

public class MyClass {      public void method1() {}     public void method2() {}     (...)     public void methodN() {}  } 

Now I would like to create a wrapper class which would delegate all the methods to wrapped instance (delegate):

public class WrapperClass extends MyClass  {     private final MyClass delegate;      public WrapperClass(MyClass delegate) {         this.delagate = delegate;     }      public void method1() { delegate.method1(); }     public void method2() { delegate.method2(); }     (...)     public void methodN() { delegate.methodN(); }  } 

Now if MyClass has a lot of methods I would need to override each of them which is more or less the same code which just "delegates". I was wondering if it is possible to do some magic to automatically call a method in Java (so the Wrapper class would need to say "Hey if you call a method on me just go to delegate object and call this method on it).

BTW: I can not use inheritance because the delegate is not under my control.I just get its instance from elsewhere (another case would be if MyClass was final).

NOTE: I do not want IDE generation. I know I can do it with help of IntelliJ/Eclipse, but I'm curious if this can be done in code.

Any suggestions how to achieve something like this? (NOTE: I would probably be able to do it in some scripting languages like php where I could use php magic functions to intercept the call).

like image 993
walkeros Avatar asked May 20 '15 08:05

walkeros


People also ask

What are delegate methods in Java?

Delegation is simply passing a duty off to someone/something else. Delegation can be an alternative to inheritance. Delegation means that you use an object of another class as an instance variable, and forward messages to the instance.

Is delegation same as inheritance?

Delegation is an alternative to inheritance for reusing code among multiple classes. Inheritance uses the IS-A relationship for re-use; delegation uses the HAS-A reference relationship to do the same. Inheritance and delegation have the same kind of relationship that, say, Aspirin and Tylenol, have.

Does delegation promote code reuse?

Similar to the inheritance pattern, the delegation pattern in object-oriented programming permits code reuse.

Do we have delegates in Java?

“Delegates” is a feature in C++ but not Java.


1 Answers

Perhaps the dynamic Proxy of java can help you. It only works if you consequently use interfaces. In this case, I will call the interface MyInterface and set up a default implementation:

public class MyClass implements MyInterface {      @Override     public void method1() {         System.out.println("foo1");     }      @Override     public void method2() {         System.out.println("foo2");     }      @Override     public void methodN() {         System.out.println("fooN");     }      public static void main(String[] args) {         MyClass wrapped = new MyClass();         wrapped.method1();         wrapped.method2();         MyInterface wrapper = WrapperClass.wrap(wrapped);         wrapper.method1();         wrapper.method2();     }  } 

The wrapper class implementation would look like:

public class WrapperClass extends MyClass implements MyInterface, InvocationHandler {      private final MyClass delegate;      public WrapperClass(MyClass delegate) {         this.delegate = delegate;     }      public static MyInterface wrap(MyClass wrapped) {         return (MyInterface) Proxy.newProxyInstance(MyClass.class.getClassLoader(), new Class[] { MyInterface.class }, new WrapperClass(wrapped));     }      //you may skip this definition, it is only for demonstration     public void method1() {         System.out.println("bar");     }      @Override     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         Method m = findMethod(this.getClass(), method);         if (m != null) {             return m.invoke(this, args);         }         m = findMethod(delegate.getClass(), method);         if (m != null) {             return m.invoke(delegate, args);         }         return null;     }      private Method findMethod(Class<?> clazz, Method method) throws Throwable {         try {             return clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());         } catch (NoSuchMethodException e) {             return null;         }     }  } 

Note that this class:

  • extends MyClass, to inherit a default implementation (any other would do)
  • implements Invocationhandler, to allow the proxy to do reflection
  • optionally implement MyInterface (to satisfy the decorator pattern)

This solution allows you to override special methods, but to delegate all others. This will even work with sub classes of Wrapper class.

Note that the method findMethod does not yet capture the special cases.

like image 167
CoronA Avatar answered Sep 20 '22 10:09

CoronA