Clojure使用Java方法

Clojure有一个很强大的功能,就是你可以使用Lisp语言风格无缝的调用java api(java interop)。这无疑是如虎添翼。

调用一个Java对象的方法

语法:

  1. .method-name object-value args ...

例如:

  1. (.toUpperCase "hello,clojure")
  2. "HELLO,CLOJURE"
  3. (.indexOf "hello,clojure" "j")
  4. 9
  5. (. "hello,clojure" indexOf "j")
  6. 9
  7. (.. System (getProperties)(get "os.name"))
  8. "Mac OS X"
  9. (.substring "hello,clojure" 6)
  10. "clojure"

其实都是使用dot operator

  1. (. object-expr-ot-classname-symbol method-or-member-symob optional-args*)

设置一个Java对象的共有成员变量

语法如下:

  1. (set! (.member-variable object-variable) new-value)

比如:

  1. (let [pt (Point. 0 10)]
  2. #_=> (set! (.y pt) 100)
  3. #_=> (.y pt))
  4. 100

调用静态共有成员变量/函数

用/分开类和成员

  1. (java.lang.Math/abs -3)
  2. 3
  3. (java.lang.Math/pow 2 10)
  4. 1024.0

创建一个对象

两种方法

  1. (Class-name. arg1 arg2 ...)

注意,类名后面有个.(a dot)这个最常用;

还有就是

  1. (new Class-name arg1 arg2 ...)

new的后面类名,构造函数里面的参数不需要使用括号()

  1. user=> (String. "Clojure!")
  2. "Clojure!"
  3. user=> (new String("Clojure"))
  4. ClassCastException java.lang.String cannot be cast to clojure.lang.IFn user/eval1266 (form-init7793881567968869401.clj:1)
  5. user=> (new String "Clojure")
  6. "Clojure"

连续调用一个对象的方法

将多个操作(多行代码)通过点号”.”链接在一起成为一句代码,我们称之为”链式编程风格”。 链式代码通常要求操作有返回值, 但对于很多操作大都是void型,什么也不返回,这样就很难链起来了.

我们在Clojure中这样来写

  1. user=> (doto (java.util.Stack.)
  2. #_=> (.push "Hello!")
  3. #_=> (.push "Clojure.")
  4. #_=> )
  5. ["Hello!" "Clojure."]
  6. com.lightsword=> (doto (java.util.HashMap.)(.put "k" 1)(.put "v" 2))
  7. {"v" 2, "k" 1}

import java package

语法

  1. (import [package.name1 ClassName1 ClassName2]
  2. [package.name2 ClassName3 ClassName4])

实例

  1. user=> (import [java.util Date Stack]
  2. #_=> [java.net Proxy URI])
  3. java.net.URI
  4. user=> (Date.)
  5. #inst "2016-06-28T15:19:05.923-00:00"

放入namespace中是推荐的写法,也就是前面加上ns:

  1. user=> (ns com.lightsword
  2. #_=> (:import [java.util Date Stack]
  3. #_=> [java.net Proxy URI])
  4. #_=> )
  5. nil
  6. com.lightsword=> (Date.)
  7. #inst "2016-06-28T15:21:43.048-00:00"

访问一个类的内部类

用如下形式:

  1. package.class-name$inner-class