iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 19
0
Software Development

擁抱 Clojure系列 第 19

[第 19 天] 擁抱 Clojure:與 Java 共舞(一)

與 Java 共舞(一)

Clojure 寄生於 Java 之中,汲取它的養分並試圖解放它的繁重。Java 有優秀的即時編譯 (Just-in-time compilation) 功能、垃圾資源回收 (Garbage collection)、HotSpot 虛擬機器與傑出的位元組程式碼。寄宿在其上的語言,不需自行實現便可以擁有強大的武器爲後援。

既然寄宿在 Java 之上,不能只理解 Clojure,而對 Java 視而不見。了解 Java 是認識平台、優秀的生態圈與工具,讓程式邁向卓越的方法。

本篇文章會從 Clojure 方呼叫 Java,以及 Java 方呼叫 Clojure 兩方面,爲各位介紹如何與 Java 共同合作。

從 Clojure 呼叫 Java

載入 Java 套件庫與類別

Clojure 中載入 Java 套件庫的方法在先前的文章也有提到過,就是使用 import 載入 Java 函式庫:

(import java.util.Date)
(Date.)
;; => #inst "2017-12-31T15:51:54.105-00:00"

以上載入 java.util.Date 套件到目前的命名空間後,就可以順利使用 Date 類別。你也可以同時載入同個套件內的不同類別:

(import java.util.Date java.util.Calendar)
;; => java.uti.Calendar

也可以使用下面範例載入同個套件下的類別:

(import '(java.util Date Calendar)
        '(java.net URI ServerSocket))
;; => java.net.ServerSocket

創建執行個體

Clojure 使用 new 特殊形式 (Special form) 來創建 Java 類別的執行個體 (Instance),第一個參數是類別名稱,接著是該類別建構式的各個參數,返回值爲該類別的執行個體:

(def date (new java.util.Date))
date
;; => #inst "2017-12-31T17:10:35.227-00:00"

Clojure 提供了語法糖 (Syntactic Sugar),用來簡化頻繁輸入 new,只要在類別名稱之後加上點 (.) 即可:

(String. "Hello")
;; => "Hello"

存取成員

由於 Clojure 中的字串即是 Java 的字串類別 java.util.String,可以在 java.util.String 類別上使用的方法 (Method),都可以在 Clojure 字串使用,例如將文字改成大寫與小寫:

(. "Hello World" toUpperCase)
;; => “HELLO WORLD”
(. "Hello World" toLowerCase)
;; => “hello world”

使用方式就是在列表中的第一個位置放上點 (.),依序再放上執行個體 (Instance) 以及方法的名稱,如果還有參數則再依序放上方法的參數:

(. "Hello World" indexOf "ello")
;; => 1

Clojure 也爲此提供了語法糖,只要將方法名稱放在列表的第一個位置,並在方法名稱之前加上點 (.),之後列表的位置依序放入執行個體以及方法的參數即可:

(.toUpperCase "Hello World")
;; => “HELLO WORLD”
(.indexOf "Hello World" "ello")
;; => 1

靜態方法 (Static method) 以及靜態欄位 (Static field) 可以使用如上用點的方式呼叫,也可以使用語法糖 Class/Method 的方式:

(. java.lang.Math PI)
;; => 3.141592653589793
java.lang.Math/PI
;; => 3.141592653589793

還有可以簡化層層內嵌運算式的特殊形式,即是在運算式的第一個位置,放上兩個點符號 (.),用來將以下的範例簡化:

(. (. (. " Hello " trim) toUpperCase) length)
;; => 5

以上範例先將字串前後空白去除,再將字串轉成大寫,之後算出字串的長度。最裡頭的運算式求值之後取得新的執行個體,再傳遞給下一個運算式求值,Clojure 則提供了兩個點符號的特殊形式,將內嵌多層的運算式變得平坦,更易寫、易讀和易於理解:

(.. " Hello" trim toUpperCase length)
;; => 5

(未完待續)


上一篇
[第 18 天] 擁抱 Clojure:資料型態與協定(二)
下一篇
[第 20 天] 擁抱 Clojure:與 Java 共舞(二)
系列文
擁抱 Clojure30

尚未有邦友留言

立即登入留言