天天看点

Java混合编程调用Java在java中调用Clojure在java中调用Kotlin

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
           

在java中调用Kotlin