clojure 新手指南(10):與java交互

clojure是基於jvm的語言,就是說clojure會被編譯成字節碼被jvm執行。可是clojure能作的可不單單是被編譯成字節碼,它提供了一套API讓用戶與java交互。所以clojure能夠直接調用java世界中那些豐富龐大的優秀庫了。 java

數據&轉換

=>12.56
12.56
在clojure中,咱們使用數據時彷佛並無像其餘語言那樣須要一些特殊的處理或者聲明。可是,clojure在底層實際建立了java對象,並指定了對應的java類型。咱們能夠經過class函數來看一下編譯器爲咱們建立的數據的類型。
=>(class 12.56)
java.lang.Double
上面咱們能夠看出,clojure自動爲咱們建立了一個Double類型的java對象。

若是咱們想在clojure指定對應的java類型,能夠這麼作: jvm

=>(new java.lang.Float 12.56)
12.56

=>(class (new java.lang.Float 12.56))
java.lang.Float
new 也是一個函數,咱們使用它建立了一個Float類型的對象,貌似比java還麻煩。clojure給咱們提供了一個更簡潔的語法來作一樣的事情。咱們在對應的構造函數名字後加一個點,而後後面依次寫上構造函數須要的參數便可。
=>(Float. "12.56")
12.56

=>(class (Float. "12.56"))
java.lang.Float
這裏 Float. 就是Float的構造函數名加上一個點。這可不是clojure的函數調用。咱們可使用fn?測試一下,Floag.並非函數。應該只是clojure的特殊的語法調用吧。

下面是一些將字符串轉換爲數字的例子: 函數

=>(+ "12.56"  "5.92")
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

=>(class "12.56")
java.lang.String

=>(+ (Float. "12.56")(Float. "5.92"))
18.48

=>(+ (Float. "12.5648230948234")(Float. "5.92"))
18.484823

=>(+ (Double. "12.5648230948234")(Double. "5.92"))
18.484823094823398

日期和時間函數

clojure自己並無專門的日期和時間處理函數。不過不用擔憂,java有的功能,clojure基本上均可以去調用。並且一旦咱們用clojure函數將java的方法包裝後,咱們後面的調用就不再會和java打交道了。 測試

下面就看看如何使用java接口來創造咱們本身的日期時間函數。讓咱們從調用系統當前時間開始吧。這一次咱們先採用一種「斜線調用」形式。咱們使用斜線一次隔開類名和調用的靜態方法名稱。咱們將要調用java中的 System.currentTimeMillis()方法來獲取當前系統時間的毫秒數。 spa


=>(defn msec []                   ;;使用函數msec包裝
    (System/currentTimeMillis))   ;;這裏的斜線至關於java中的 "."
#'user/msec

=>(msec)                          ;;調用msec,返回當前系統時間毫秒數 
1307328017335

=>(msec)
1307662973116

=>(> 1307328017335 1307662973116)
false

=>(> 1307662973116 1307328017335)
true

上面是靜態方法調用的展現,下面再來看看若是調用實例方法。讓咱們建立兩個java.util.Date對象。注意,以前咱們使用的都是java.lang下面的類,因此不須要手動導入。非lang包下的必須手動導入(和java同樣同樣的)。 翻譯

=>(Date.)                   ;;導入前,找不到Date類
java.lang.IllegalArgumentException: Unable to resolve classname: Date...

=>(import java.util.Date)   ;;手動導入Date (語法都和java同樣)
java.util.Date              

=>(Date.)                   ;;再次建立Date對象 
#<Date Sun Jun 05 20:48:19 MDT 2011>

=>(class (Date.))           ;;查看一下對象類型,確實是 java.util.Date
java.util.Date

如今咱們來用clojure來包裝一下,咱們創造一個名爲date的函數。該函數有兩種參數形式:無參數和接受毫秒值(對應Date 的無參構造函數和 Date(long time)構造函數)。 code


=>(defn date                     ;;使用函數date封裝java API
    ([](Date.))                  ;;第一種是無參數模式
    ([systime](Date. systime)))  ;;第二種是接受一個參數
#'user/date

=>(date)	                   ;;調用date函數,無參數
#<Date Sun Jun 05 20:41:42 MDT 2011>

=>(date 1307328017335)           ;;調用date函數,傳入一個long值
#<Date Sun Jun 05 20:40:17 MDT 2011>
爲了讓咱們時間處理在強大點,咱們在利用java庫中的 SimpleDateFormat類將時間轉換成特定形式的字符串。


=>(import java.text.SimpleDateFormat)                 ;;導入須要的類
java.text.SimpleDateFormat

=>(defn format-date                                   ;;使用自定義函數封裝
    ([](format-date (date) "yyyy MM dd HH mm ss"))
    ([x](if (string? x)
            (format-date (date) x)
            (format-date x "yyyy MM dd HH mm ss")))
    ([dt fmt](.format (SimpleDateFormat. fmt) dt)))
#'user/format-date

=>(format-date)
"2011 06 04 17 50 21"

=>(format-date (date 404534000000))
"1982 10 26 20 33 20"

=>(format-date "yyyy/MM/dd HH:mm:ss")
"2011/06/04 17:51:00"

=>(format-date (date 404534000000) "yyyy/MM/dd HH:mm:ss")
"1982/10/26 20:33:20"
其餘沒有什麼難點,都是以前說過的內容,咱們主要解釋上面代碼中下面這一句的意義:


([dt fmt](.format (SimpleDateFormat. fmt) dt)))
[dt fmt]是參數列表,這個沒什麼特別的東西。主要看看函數體。 .format 是方法名 (SimpleDateFormat.  fmt)最終返回的是 SimpleDateFormat類型的對象(至關於調用 new SimpleDateFormat(fmt)) ,dt 是參數因此整個意思是調用實例  (SimpleDateFormat.  fmt)的format 方法,並傳入參數dt。翻譯成java代碼就是:
(new SimpleDateFormat(fmt)).format(dt)
很簡單吧。我的以爲使用clojure封裝後的java代碼比本來的java API更要緊湊和靈活。這主要依靠了clojure這種動態語言+函數式語言的N多優點。
相關文章
相關標籤/搜索