Accessing fields, methods of Java classes that aren't imported in Clojure -
i'm starting more clojure-java interop. if create java class in clojure, need import it, if merely use fields or methods of class, don't have import it. example:
(ns students.student (:import [sim.util double2d]) (defn -step [this students] ; students students.students, extends sim.engine.simstate (let [yard (.-yard students) ; sim.field.continuous.continuous2d yard-width (.-width yard) yard-height (.-height yard)] (.setobjectlocation yard (double2d. (/ yard-height 2) (/ yard-width 2))))) this won't compile without importing double2d, because code creates double2d instance.
however, fact access yard field , setobjectlocation() method of students instance, , width , height fields of continuous2d instance causes no problems, though don't import students or continuous2d classes.
does mean clojure using reflection @ runtime access java fields , methods? inefficient? if need speed in function, advantageous add type declarations java classes, along missing import statements? prevent reflection?
[edit: second comment on arthur ulfeldt's answer suggests, think inefficiencies come not knowing classes @ compile time not different inefficiencies come fact functions contained in variables. if worried that, i'd forget clojure , program in pure java (maybe), instead of trying use java libs clojure. me, world in can use clojure instead of java better one.]
import used make you don't have type full name of class, including it's package name, each time want use it. if class on classpath can call it's full name anywhere. if import statement can call class name, though within namespace import exists.
i'll start new project , add dependency not used anywhere in default project, in case riemann client monitoring stuff (it's great program check out)
lein new hello and add dep
(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"]]) then first thing, i'll @ class it's full name without import
hello.core> com.aphyr.riemann.client.riemannclient com.aphyr.riemann.client.riemannclient then try short name:
hello.core> riemannclient compilerexception java.lang.runtimeexception: unable resolve symbol: riemannclient in context, compiling:(/tmp/form-init3055907211270530213.clj:1:5933) which not work:
hello.core> (import '[com.aphyr.riemann.client riemannclient]) com.aphyr.riemann.client.riemannclient then if add import , try again:
hello.core> riemannclient com.aphyr.riemann.client.riemannclient the name resolves within user namespace.
if change namespaces:
hello.core> (in-ns 'foo) and @ class again:
foo> riemannclient compilerexception java.lang.runtimeexception: unable resolve symbol: riemannclient in context, compiling:(/tmp/form-init3055907211270530213.clj:1:5933) foo> com.aphyr.riemann.client.riemannclient com.aphyr.riemann.client.riemannclient we can see imports per-namespace, though classes on classpath available everywhere.
Comments
Post a Comment