clojureclojure-java-interop

create clojure proxy of abstract java class with overloaded same-arity method


is it possible to proxy a class like this and override both methods?

public abstract class C {
  ...
  public abstract void m(String a);
  public void m(Integer a) {}
}

this doesn't work:

(proxy [C] []
  (m [^String a])
  (m [^Integer a]))

;; java.lang.IllegalArgumentException: Method 'm' redefined

my current workaround is to write a proxy-friendly java class that renames the overload:

public abstract class C2 extends C {
  @Override
  public void m(Integer a) { this.m2(a); }
  public abstract void m2(Integer a);
}

but would be nice to have a solution that doesn't require javac in the build


Solution

  • Include one method m in your proxy. Do not type-hint the parameter. Let the function check the actual parameter type at run-time and behave accordingly.

    (If the methods in question differed in arity, you would need to declare the proxy method argument list as [ & x], i.e., receiving all parameters, however many they might be, as a vector. This technique helps when you want to proxy java.io.Writer for example.)