0

Background

Consider the objects Alice, Bob, and Eve. In Smalltalk, Alice can send a message to Bob that Bob then delegates to Eve, without Bob knowing the name of the method to delegate (see Smalltalk delegation of an unknown method call).

Problem

Java can partially emulate Smalltalk's behaviour by coding Alice like:

public void methodName() {
  Object bob = new Bob();

  try {
    ((BobInterface)bob).methodName();
  }
  catch( ClassCastException e ) {
    ((BobInterface)bob).doesNotUnderstand( new Method( name ) );
  }
}

This captures the intent, but is verbose and repetitious (being codified once per method). It can be impractical even if the code is generated.

Java 8 introduces lambda expressions (see this SO answer).

Question

How could you codify Bob such that all method invocations that Bob does not implement are passed from Alice to Eve via Bob?

For example, a variation of the following should display Received Alice's message!:

public class Alice {
  public static void main( String args[] ) {
    Bob bob = new Bob();

    // Problematic line...
    bob.listen();
  }
}

public class Bob {
  private Eve eve;

  // When "bob.listen()" is called, this should be invoked...
  public void doesNotUnderstand( Method m ) {
    delegate( eve, m );
  }
}

public class Eve {
  public void listen() {
    System.out.println( "Received Alice's message!" );
  }
}

Problem Constraints

  • Lambda expressions, reflection, or both are welcome.
  • Third-party libraries (e.g., bytecode manipulation) and aspects are not ideal.
  • Bob can not implement more than one method nor inherit any methods.
  • Neither Alice nor Bob should contain repetitious code.

Ideas

Method names can be retrieved by implementing local classes:

public class T {
   public static void main( String args[] ){
      class Local {};
      String name = Local.class.getEnclosingMethod().getName();
      System.out.printf( "%s%n", name );
   }
}

Related

Community
  • 1
  • 1
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315

1 Answers1

0

I don't think anything like this is possible at runtime. For the code to compile, you would at least need an interface which "understands" all methods. Sure you can use reflection and invoke everything dynamically but you lose all the type safety. The only way I could see this working is to use some kind of (precompile) code generation (you could even use standard java annotations if you dont want to rely on third party libraries).

Ueli Hofstetter
  • 2,409
  • 4
  • 29
  • 52