'How do I call overloaded Java methods in Clojure

For this example Java class:

package foo;
public class TestInterop
{   public String test(int i)
    { return "Test(int)"; }

    public String test(Object i)
    { return "Test(Object)"; }
}

When I start Clojure and try to call the test(int) method, the test(Object) method is called instead, because Clojure automatically boxes the integer into a java.lang.Integer object.

How do I force Clojure to call the test(int) method?

user=> (.test (new foo.TestInterop) 10)
"Test(Object)"

I want to call methods like Component.add(Component comp, int index) in AWT, but instead keep calling add(Component comp, Object constraints), so the buttons on my toolbar always appear in the wrong order.



Solution 1:[1]

user=> (.test (foo.TestInterop.) 10)
"Test(Object)"
user=> (.test (foo.TestInterop.) (int 10))
"Test(int)"

Numbers in Clojure are generally boxed (int => Integer) unless you specifically ask for primitives.

Here is more information about primitives in Clojure.

Solution 2:[2]

To call Container.add(Component child, int index) use

(.add ^Container container ^Component child ^int index)

Or you can add the type hints for Container and Component earlier, but the type hint for int must be in the call to add. For example,

(defn add-component [^Container container ^Component component index]
    (.add container component ^int index)

The primitive type int may not be used as a type hint in a fn definition. I'm not sure where else it may be used, so AFAIK it must appear directly on the method call unless a number literal is used, in which case no type hint is necessary in my experience.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brian Carper
Solution 2 Jason