Переопределение методов множественности в прокси в clojure

У меня есть класс Java, который имеет 2 метода с одинаковыми, но разными значениями (один не принимает аргументов, другой принимает 1 аргумент). Я создаю прокси, который переопределяет оба этих метода. Проблема в том, что если из этого java-класса вызывается метод без аргументов - вызывается базовая реализация вместо прокси. Но если я вызываю метод без аргументов непосредственно на obj - вызывается правильный метод прокси. Может кто-нибудь объяснить такое поведение?

Тест.java:

package example;

public abstract class Test {

    public void callMethods(Object obj){
        callMethods();
        callMethods2();
    }

    public void callMethods() {
        System.out.println("Default callMethods");
    }

    public void callMethods2() {
        System.out.println("Default callMethods2");
    }

}

запустить.clj:

(let [obj (proxy [example.Test] []
            (callMethods
              ([] (println "Overridden callMethods"))
              ([obj] (proxy-super callMethods obj)))
            (callMethods2
              ([] (println "Overridden callMethods2"))))]
  (.callMethods obj)
  (.callMethods obj :test))

Выход:

Overridden callMethods
Default callMethods
Overridden callMethods2

Ожидаемый результат:

Overridden callMethods
Overridden callMethods
Overridden callMethods2

person Mikita Belahlazau    schedule 30.10.2012    source источник


Ответы (1)


Proxy поддерживает карту методов, которые он проксирует для этого объекта. Любой вызов на этой карте обрабатывается своим методом, остальные вызывают объект. proxy-super творит чудеса, удаляя себя из карты методов функций, вызывая себя и возвращая себя после слов. Во время вызова любые вызовы этого метода прокси-объекта будут переданы проксируемому объекту.

  • Первая строка вывода исходит от прокси-вызова, и вы видите переопределенный вывод.
  • Вторая строка исходит из метода super с нулевыми аргументами, потому что, когда происходит этот вызов, переопределяющий метод отсутствует в карте прокси-методов объектов.
  • Третья строка получает проксирование, потому что этот метод находится в карте проксированных методов объектов.

Очень похожий сценарий описан в конце этого сообщения Мейкеля Брандмейера. . Я подозреваю, что ответ заключается в использовании gen-class вместо прокси.

person Arthur Ulfeldt    schedule 30.10.2012