如何在Clojure中调用重载的Java方法 [英] How do I call overloaded Java methods in Clojure

查看:130
本文介绍了如何在Clojure中调用重载的Java方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于此示例Java类:

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



当我开始Clojure并尝试调用test调用测试(Object)方法,因为Clojure自动将整数转换为java.lang.Integer对象。

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.

如何强制Clojure调用测试int)method?

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

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

我想在AWT中调用 Component.add(Component comp,int index)的方法,而是继续调用 add(Component comp,Object constraints)

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.

推荐答案

我的工具栏上的按钮总是以错误的顺序出现。在Freenode的#clojure频道刚刚在这个非常主题。克里斯·霍舍尔(谁将要发布一个答案,但最终决定他太忙,不能这样做)已张贴一个精神,它演示了 boolean 对象重载方法发生的情况;事实证明,在某些情况下,除了(boolean ...) cast,需要类型提示。讨论是相当启发,有一些黑暗的角落的Clojure编译过程变得很好地照亮。 (参见下面的IRC日志链接。)

A discussion is going on in the #clojure channel on Freenode just now on this very topic. Chris Houser (who was going to post an answer, but ultimately decided he was too busy to do it) has posted a Gist which demonstrates what happens with a boolean vs. Object overloaded method; it turns out that in some scenarios, in addition to a (boolean ...) cast, a type hint is required. The discussion was quite enlightening, with a few dark corners of Clojure compilation process becoming nicely illuminated. (See links to IRC log below.)

基本上,如果一个对象在方法调用表单中创建 - (。foo Foo。)...),说 - 类型提示不是必需的;如果对象已经被构造为在封闭的 let 形式中的局部变量的值(见下面的更新2和我的版本的Gist),则没有必要。然而,如果通过Var查找获得对象,则需要类型提示 - 其可以在Var本身上或者在调用位置处用于指代Var的符号上提供。

Basically, if an object is created right in the method-calling form -- (.foo (Foo.) ...), say -- that type hint is not necessary; it is likewise not necessary if the object has been constructed as a value for a local in an enclosing let form (see update 2 below and my version of the Gist). If the object is obtained by Var lookup, though, a type hint is required -- which can be provided either on the Var itself or, at the call site, on the symbol used to refer to the Var.

来自Gist的Java代码:

The Java code from the Gist:

package mypkg;

public class Ugly {
    public Ugly(){}
    public String foo(boolean i) { return "bool: " + i; }
    public String foo(Object o) { return "obj: " + o; }
}

Clojure代码:

And the Clojure code:

(.foo (mypkg.Ugly.) 5)
;=> "obj: 5"

(.foo (mypkg.Ugly.) true)
;=> "obj: true"

(.foo (mypkg.Ugly.) (boolean true))
;=> "bool: true"


(def u (mypkg.Ugly.))
(.foo u (boolean true))
;=> "obj: true"

(.foo #^mypkg.Ugly u (boolean true))
;=> "bool: true"

注意Clojure编译器需要在 u 以便能够编译直接方法调用。否则,似乎会产生基于反射的代码,这显然失去了这样一个事实的轨迹,这个参数是一个原始的沿途。

Note how the Clojure compiler needs a type hint on u to be able to compile a direct method call. Otherwise reflection-based code seems to be generated, which apparently loses track of the fact that the argument is meant to be a primitive along the way.

我的补充跟随这里是我的上述Gist的叉子)。

My additions follow (and here's my fork of the above Gist).

;; renamed mypkg.Ugly to foo.TestInterop2 when doing my tests
user> (let [t (foo.TestInterop2.)]
        (.foo t (boolean true)))
"bool: true"

;;; type-hinting the Var
user> (def #^foo.TestInterop2 x (foo.TestInterop2.))
#'user/x
user> (.foo x (boolean true))
"bool: true"

请先在此处提出。 Chouser在半小时后发布了Gist ,之后讨论变得越来越有趣。

The topic was first brought up at this point. Chouser posted the Gist half an hour later, with the discussion becoming more and more interesting after that.

这篇关于如何在Clojure中调用重载的Java方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆