gpt4 book ai didi

java - 访问未在 Clojure 中导入的 Java 类的字段和方法

转载 作者:行者123 更新时间:2023-11-29 03:10:06 25 4
gpt4 key购买 nike

我开始更深入地了解 Clojure-Java 互操作。如果我在 Clojure 中创建一个 Java 类,我需要导入它,但如果我只是使用类的字段或方法,则不必导入它。例如:

(ns students.Student
(:import [sim.util Double2D])

(defn -step
[this students] ; students is a students.Students, extends sim.engine.SimState
(let [yard (.-yard students) ; a sim.field.continuous.Continuous2D
yard-width (.-width yard)
yard-height (.-height yard)]
(.setObjectLocation yard this (Double2D. (/ yard-height 2) (/ yard-width 2)))))

如果不导入 Double2D 就无法编译,因为代码创建了一个 Double2D 实例。

但是,事实上我访问了 students 实例的 yard 字段和 setObjectLocation() 方法,以及 width Continuous2D 实例的 height 字段不会导致任何问题,即使我不导入 StudentsContinuous2D 类。

这是否意味着 Clojure 在运行时使用反射来访问 Java 字段和方法?那是低效的吗?如果我需要一个函数的速度,那么为 Java 类添加类型声明以及缺少的导入语句是否有利?这会阻止反射吗?

[编辑:正如我对 Arthur Ulfeldt 的回答的第二条评论所暗示的那样,我现在认为,由于在编译时不知道类而导致的任何低效率可能与由于函数包含在变量。如果我担心那个,我会忘记 Clojure 和纯 Java 编程(可能),而不是尝试使用 Clojure 中的 Java 库。对我来说,一个我可以使用 Clojure 而不是 Java 的世界是一个更好的世界。]

最佳答案

导入只是用来做的you don't have to type the full name of the class ,包括它的包名称,每次你想使用它。 如果一个类在类路径中,您可以从任何地方通过它的全名调用它。如果您作为 import 语句,您可以仅通过类名调用它,但只能从存在该导入的 namespace 内调用。

我将从一个新项目开始,并添加一个显然在默认项目中的任何地方使用的依赖项,在本例中是用于监视内容的 Riemann 客户端(这是一个很棒的程序,请查看)

lein new hello

并添加部门

(defproject hello "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:aot :all
:main hello.core
:profiles {:uberjar {:aot :all}}
:dependencies [[org.clojure/clojure "1.6.0"]
[com.aphyr/riemann-java-client "0.3.1"]])

然后首先,我将通过它的全名来查看该类,不带任何导入

hello.core> com.aphyr.riemann.client.RiemannClient
com.aphyr.riemann.client.RiemannClient

然后试试简称:

hello.core> RiemannClient
CompilerException java.lang.RuntimeException: Unable to resolve symbol: RiemannClient in this context, compiling:(/tmp/form-init3055907211270530213.clj:1:5933)

这是行不通的:

hello.core> (import '[com.aphyr.riemann.client RiemannClient])
com.aphyr.riemann.client.RiemannClient

然后如果我们添加导入并重试:

hello.core> RiemannClient
com.aphyr.riemann.client.RiemannClient

名称从用户命名空间内解析。
如果我更改 namespace :

hello.core> (in-ns 'foo)

然后再看看类:

foo> RiemannClient
CompilerException java.lang.RuntimeException: Unable to resolve symbol: RiemannClient in this context, compiling:(/tmp/form-init3055907211270530213.clj:1:5933)
foo> com.aphyr.riemann.client.RiemannClient
com.aphyr.riemann.client.RiemannClient

我们可以看到导入是按命名空间进行的,尽管类路径上的类随处可用。

关于java - 访问未在 Clojure 中导入的 Java 类的字段和方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29858336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com