主页
主页
文章目录
  1. Table of Contents
  2. 1 使用 java 文件
  3. 2 创建实例
  4. 3 方法和成员变量
    1. 3.1 静态方法
    2. 3.2 公开非静态方法
    3. 3.3 公开成员变量
  5. 4 .. 宏
  6. 5 doto

Clojure 与 Java 交互

作为活在jvm上的语言,并且把使用 java 库作为自己的优势,与 java 的调用绝不可避免。所以,这个知识很重要。

1 使用 java 文件

之前在 ns 中,有说过这个,如何引入 java 的文件。

语法: (import & import-symbols-or-lists)

实例:

(import
'(org.apache.hadoop.hbase.client HTable Scan Scanner)
'(org.apache.hadoop.hbase.filter RegExpRowFilter StopRowFilter))


;; 或者
(ns com.clojureinaction.book
(:import (java.util Set)))

2 创建实例

一个实例的创建,通过类名和一个点(.)即可,如下:

(import '(java.text SimpleDateFormat))
(def sdf (Simpledateformat. "yyyy-MM-dd"))

3 方法和成员变量

3.1 静态方法

静态方法调用,语法: (Classname/staticMethod args)。

实例如下:

(Long/parseLong "12321")

3.2 公开非静态方法

采用一个 . 宏操作符号,实例如下:

(defn date-from-date-string [date-string]
(let [sdf (SimpleDateFormat. "yyyy-MM-dd")]
(.parse sdf date-string)))

同时还有一种方法,格式为: (. Classname-symbol method-symbol args) 或者 (. Classname-symbol (method-symbol args))

实例如下:

(import '(java.util Random))
(let [rnd (Random. )]
(. rnd (nextInt 10)))

;; 也可以写成: (.nextInt rnd 10)

3.3 公开成员变量

使用 . 宏操作,还可以获取到类的成员变量,格式为: (. Classname-symbol member-symbol) 或者 (. instance-expr member-symbol)

实例如下:

(. Calendar DECEMBER)

4 .. 宏

写过 java 的都知道,这个语言比较啰嗦。以 《Clojure in Action》中的获取当前时区名字为例, 按照 . 的用法,是可以逐步获取日历的实例,然后点操作获取时区类,再点操作获取时区名,需要进行嵌套,代码比较冗长,会是下面这个样子:

(import '(java.util Calendar TimeZone))
(. (. (Calendar/getInstance) (getTimeZone)) (getDisplayName))

这样的代码看上去简直难以接受,类的获取再深入一点,可能要嵌套多层。 .. 宏就是应对这个问题的,使用 .. 之后,代码如下:

(import '(java.util Calendar TimeZone))
(..
(Calendar/getInstance)
(getTimeZone)
(getDisplayName true TimeZone/SHORT))

最后一个 getDisplayname 方法接收了两个参数。

5 doto

doto 是一个懒人宏,主要是为了一个实例,连续调用它的N个方法设立的。比如以下这个给日历设置时间的操作:

(import '(java.util Calendar))
(defn the-past-midnight-1 []
(let [calendar-obj (Calendar/getInstance)]
(.set calendar-obj Calendar/AM_PM Calendar/AM)
(.set calendar-obj Calendar/HOUR 0)
(.set calendar-obj Calendar/MINUTE 0)
(.set calendar-obj Calendar/SECOND 0)
(.set calendar-obj Calendar/MILLISECOND 0)
(.getTime calendar-obj)))

有了 doto 后,会少一些代码。如下:

(defn the-past-midnight-2 []
(let [calendar-obj (Calendar/getInstance)]
(doto calendar-obj
(.set Calendar/AM_PM Calendar/AM)
(.set Calendar/HOUR 0)
(.set Calendar/MINUTE 0)
(.set Calendar/SECOND 0)
(.set Calendar/MILLISECOND 0))

(.getTime calendar-obj)))

常用的操作就这些,很实用很不错。

Author: HeHe

Created: 2018-11-19 一 21:44

Validate