2012-10-30 9 views
6

Ho una classe java che ha 2 metodi con le stesse ma diverse funzioni (uno non accetta argomenti, l'altro accetta 1 argomento). Creo un proxy che sostituisce entrambi questi metodi. Il problema è che se il metodo no-arg viene chiamato da questa classe java - l'implementazione base viene chiamata invece di proxie. Ma se chiamo il metodo no-arg direttamente su obj - viene invocato il metodo proxy corretto. Qualcuno può spiegare questo comportamento?Sovrascrittura dei metodi multi-arity in proxy in clojure

Test.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"); 
    } 

} 

run.clj:

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

uscita:

Overridden callMethods 
Default callMethods 
Overridden callMethods2 

uscita prevista:

Overridden callMethods 
Overridden callMethods 
Overridden callMethods2 

risposta

5

Proxy mantiene una mappa dei metodi che esegue il proxy per questo oggetto. Qualsiasi chiamata in questa mappa si gestisce con il suo metodo, gli altri chiamano l'oggetto. proxy-super è magico rimuovendo se stesso dalla mappa del metodo delle funzioni, chiamandosi e rimettendosi dietro le parole. Durante la chiamata, qualsiasi chiamata a quel metodo dell'oggetto proxy passerà all'oggetto proxy.

  • La prima riga di output deriva dalla chiamata Proxied e si vede l'uscita override
  • La seconda linea viene dal metodo del super-con zero argomenti, perché quando la chiamata avviene il metodo prioritario non è negli oggetti proxy mappa dei metodi.
  • La terza riga viene inoltrata perché tale metodo si trova nella mappa dei metodi proxy degli oggetti.

Uno scenario molto simile è descritto allo end of this post by Meikel Brandmeyer. Sospetto che la risposta sia usare la gen-class invece del proxy

Problemi correlati