JVM中运行的各种语言底层互通,先天上就具备混合编程的优势。
文章目录
- 调用Java
- 在java中调用Clojure
- 在java中调用Kotlin
调用Java
Java在JVM中的老大地位不可撼动,所以诸如Groovy,Kotlin,Scala,Clojure等都可以无痛调用。
比如在Groovy中:
C:\Users\Laser>groovysh
九月 12, 2019 6:28:42 下午 java.util.prefs.WindowsPreferences <init>
Type ':help' or ':h' for help.
groovy:000> import java.util.*
===> java.util.*
groovy:000> rand = new Random()
===> java.util.Random@34997338
groovy:000> rand.nextInt(100)
===> 9
groovy:000> rand.nextInt(100)
===> 36
groovy:000>
在Kotlin中:
C:\Users\Laser>kotlinc-jvm
Welcome to Kotlin version 1.3.50 (JRE 1.8.0_144-b01)
Type :help for help, :quit for quit
>>> import java.util.*
>>> var rand = Random()
var rand = Random()>>> rand.nextInt(100)
rand.nextInt(100)res5: kotlin.Int = 90
在scala中:
C:\Users\Laser>scala
Welcome to Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.
scala> import java.util
scala> val rand = new util.Random()
rand: java.util.Random = java.util.Random@530ee28b
scala> rand.nextInt(100)
res0: Int = 59
Clojure这个Lisp方言有点特立独行,毕竟不是面向对象语言,本身就与java水土不服,但也可以调用
C:\Users\Laser>lein repl
user=> (def randn (java.util.Random.))
#'user/randn
user=> (.nextInt randn 100)
88
user=>
对于其他java中方法的调用,也需要改成Clojure形式,列入下表,注意Clojure中的
.
和空格。
操作 | Java | Clojure |
---|---|---|
创建类的实例 | ClassName obj = new ClassName(args) | (def obj (ClassName. args) |
调用实例方法 | obj.methodName(args) | (.methodName obj args) |
调用静态方法 | ClassName.methodName(args) | (ClassName/methodName args) |
访问静态属性 | ClassName.field | ClassName/field |
访问实例的属性 | obj.field | (.field obj) |
修改实例的属性 | obj.field = value | (set! (.field obj) value) |
引用Class | ClassName.class | ClassName |
在java中调用Clojure
首先新建一个Clojure工程,
E:\Documents\00\0913>lein new hello
E:\Documents\00\0913>tree /f hello
卷 工作 的文件夹 PATH 列表
卷序列号为 3895-5CDD
E:\DOCUMENTS\00\0913\HELLO
│ .gitignore
│ .hgignore
│ CHANGELOG.md
│ LICENSE
│ project.clj //配置文件
│ README.md
├─doc
│ intro.md
├─resources
├─src
│ └─hello
│ core.clj //源代码
└─test
└─hello
core_test.clj //测试代码
E:\Documents\00\0913>code hello
其中,
src\hello\core.clj
即新建项目的Clojure代码,默认为:
(ns hello.core)
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!"))
由于我们需要在java中调用,所以需要添加java的基础结构——类,所以对代码稍加修改:
(ns hello.core
(:gen-class ;;创建类
:methods [#^{:static true} [foo [String] String]]));;类中有一个传入str输出str的方法foo
(defn foo
"I don't do a whole lot."
[x]
(println x "Hello, World!")
(str "hello" x))
(defn -main [] (println "this is main"))
在项目目录中,project.clj为工程配置文件,将其改为
(defproject hello "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.10.0"]]
:aot [hello.core] ;;预编译
:main hello.core) ;;设置入口函数
然后回到hello目录下,进行编译和打包,得到两个jar包,即可进行调用了。也可以通过
java -jar
对执行,可见执行了
main
函数。
E:\Documents\00\0913\hello>lein compile
Compiling hello.core
E:\Documents\00\0913\hello>lein uberjar
Compiling hello.core
Compiling hello.core
Created E:\Documents\00\0913\hello\target\hello-0.1.0-SNAPSHOT.jar
Created E:\Documents\00\0913\hello\target\hello-0.1.0-SNAPSHOT-standalone.jar
E:\Documents\00\0913\hello>java -jar target\hello-0.1.0-SNAPSHOT-standalone.jar
this is main