Clojure诞生之初,是基于Java的。但是任何语言都可以解析lisp并执行,所以Clojure可以基于任何语言,只要一个大拿愿意这么干。这不,Clojurescript基于JavaScript的已经出现了, 之后又引发了另一个项目的出现ClojureC。两个项目在github上的地址:
https://github.com/clojure/clojurescript
https://github.com/schani/clojurec
现在来说说clojure与java的知识点。
在core.clj文件中,可以添加一个list (:gen-class)用来生成java class, 比如我之前的博客中用过的
(ns hello-storm-clj.core
(:import [backtype.storm StormSubmitter LocalCluster])
(:use [backtype.storm clojure config])
(:gen-class))
这样会将namespace hello-storm-clj编译成java类hello-strom-clj
参考之前的博客
主要命令是
lein do clean, uberjar
clojure的历次发布都以jar包的形式,运行的命令和所有java程序一样
java -jar clojure-1.7.0.jar
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: hudson
Build-Jdk: 1.7.0_20
Main-Class: clojure.main
package clojure;
import clojure.lang.Symbol;
import clojure.lang.Var;
import clojure.lang.RT;
public class main{
final static private Symbol CLOJURE_MAIN = Symbol.intern("clojure.main");
final static private Var REQUIRE = RT.var("clojure.core", "require");
final static private Var LEGACY_REPL = RT.var("clojure.main", "legacy-repl");
final static private Var LEGACY_SCRIPT = RT.var("clojure.main", "legacy-script");
final static private Var MAIN = RT.var("clojure.main", "main");
public static void legacy_repl(String[] args) {
REQUIRE.invoke(CLOJURE_MAIN);
LEGACY_REPL.invoke(RT.seq(args));
}
public static void legacy_script(String[] args) {
REQUIRE.invoke(CLOJURE_MAIN);
LEGACY_SCRIPT.invoke(RT.seq(args));
}
public static void main(String[] args) {
REQUIRE.invoke(CLOJURE_MAIN);
MAIN.applyTo(RT.seq(args));
}
}
java生态圈极其庞大,调用java代码可以获得巨大的资源,clojure可以使用java库是个明智的决策。很多java依赖包都是通过maven centre组织的,因此要重复利用这个资源。前面介绍过,这里重复一下。
在project.clj中添加依赖,依赖参考pom.xml的maven依赖设置,org.apache.storm是groupId, storm-core是artifactId
:dependencies [[org.clojure/clojure "1.5.1"] [org.apache.storm/storm-core "0.9.5"]]
java interop就是值clojure能够调用java代码。
形如(.method-name object-variable arg1 arg2 ...),比如:
=>(.toUpperCase "call Java String")
"CALL JAVA STRING"
=> (.length "call Java String")
16
e=> (.indexOf "call Java String" "S")
10
其实都使用的是dot operator,形如:
(. object-expr-or-classname-symbol method-or-member-symbol optional-args*)
kafka2hdfs.core=> (.indexOf "call Java String" "S")
10
kafka2hdfs.core=> (. "call Java String" indexOf "S")
10
因此两种形式都可以使用
语法如下:
比如
(import java.awt.Point)
(let [pt (Point. 0 10)]
(set! (.y pt) 100)
(.y pt)) ; ⇒ 100
(.member-varible object-variable)
用/分开类和成员
(java.lang.Math/abs -3)
; => 3
两种方法(Class-name. arg1 arg2 ...) 这个最常用,还有就是(new Class-name arg1 arg2 ...)
注意,第一个方法里面有. 不要忘记了。
=> (String. "ok")
"ok"
(doto (java.util.Stack.)
(.push "Latest episode of Game of Thrones, ho!")
(.push "Whoops, I meant 'Land, ho!'"))
(import [package.name1 ClassName1 ClassName2]
[package.name2 ClassName3 ClassName4])
比如:
(import [java.util Date Stack]
[java.net Proxy URI])
(Date.)
; => #inst "2015-09-19T20:40:02.733-00:00"
(ns pirate.talk
(:import [java.util Date Stack]
[java.net Proxy URI]))
用如下形式:package.class-name$inner-class
rotation-policy (TimedRotationPolicy. 15.0 org.apache.storm.hdfs.bolt.rotation.TimedRotationPolicy$TimeUnit/MINUTES)
public class TimedRotationPolicy implements FileRotationPolicy {
public static enum TimeUnit {
SECONDS((long)1000),
MINUTES((long)1000*60),
HOURS((long)1000*60*60),
DAYS((long)1000*60*60*24);
[org.apache.storm.hdfs.bolt.rotation TimedRotationPolicy]