2015-03-21 3 views
0

фон

Рассмотрим объекты Алиса, Боб и Ева. В Smalltalk Алиса может отправить сообщение Бобу, что Боб тогда делегирует Еве без Боба, зная имя метода для делегирования (см. Делегирование Smalltalk unknown method call).выполнения делегация неизвестного метода вызывает

Проблема

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 представлены лямбда-выражения (см. Это SO answer).

Вопрос

Как вы могли бы кодифицировать Боб таким образом, что все вызовы методов, которые Боб не реализует передаются от Алисы к Еве через Боб?

Например, изменение следующих должно отображаться 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); 
    } 
} 

Связанные

ответ

0

Я не думаю, что литий ke это возможно во время выполнения. Для компиляции кода вам потребуется хотя бы интерфейс, который «понимает» все методы. Конечно, вы можете использовать отражение и вызывать все динамически, но вы теряете все виды безопасности. Единственный способ, с помощью которого я мог видеть эту работу, - использовать какое-то (прекомпиляционное) генерирование кода (вы даже можете использовать стандартные аннотации java, если не хотите полагаться на сторонние библиотеки).