未知方法调用的运行时委派

Runtime delegation of unknown method calls

背景

考虑对象 AliceBobEve。在 Smalltalk 中,Alice 可以向 Bob 发送一条消息,然后 Bob 将消息委托给 Eve,而 Bob 不知道要委托的方法的名称(请参阅 unknown method call 的 Smalltalk 委托)。

问题

Java 可以部分地 emulate Smalltalk's behaviour 通过像这样编码爱丽丝:

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

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

这抓住了意图,但冗长且重复(每个方法编码一次)。就算生成了代码也是不切实际的。

Java 8介绍了lambda表达式(看这个SO answer)。

问题

您如何对 Bob 进行编码,以便 Bob 未实现的所有方法调用都通过 Bob 从 Alice 传递给 Eve?

例如,以下变体应显示 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!" );
  }
}

问题约束

想法

可以通过实现本地 类:

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

相关

我认为这样的事情在运行时是不可能的。对于要编译的代码,您至少需要一个包含 "understands" 所有方法的接口。当然,您可以使用反射并动态调用所有内容,但您会失去所有类型安全性。我能看到这个工作的唯一方法是使用某种(预编译)代码生成(如果你不想依赖第三方库,你甚至可以使用标准 java 注释)。