在Java中使用脚本语言
在Java中使用脚本语言
更新日期: 2020-07-28
1. 概述
在Java6中,Java增加了一个叫做ScriptEngine的组件专门用来支持脚本语言。使用这个组件可以非常方便的与各种脚本语言进行交互。
并且,使用这个组件,可以让不同的脚本语言在使用时调用统一的接口。这样就可以获得非常相似的写法,降低了学习成本。因为每种脚本语言的包提供的接口函数可能差别很大。
2. 使用ScriptEngine
这里就以lua脚本语言为例来介绍下ScriptEngine的使用。其它脚本语言也是类似的使用方法。
2.1 准备工作
首先我们要在工程中引入如下的luaj包:
在Maven中,可以很方便的引用:
Example
| <!-- https://mvnrepository.com/artifact/org.luaj/luaj-jse -->
<dependency>
<groupId>org.luaj</groupId>
<artifactId>luaj-jse</artifactId>
<version>3.0.1</version>
</dependency>
|
2.2 初始化脚本引擎
我们主要使用ScriptEngine类来进行各种交互操作,创建这个类的过程如下:
| // 脚本引擎管理器
ScriptEngineManager mgr = new ScriptEngineManager();
// 脚本引擎
ScriptEngine e = mgr.getEngineByName("lua");
|
这个类中比较重要的函数有这些:
| Object eval(String script)
// Executes the specified script.
Object eval(Reader reader)
// Same as eval(String) except that the source of the script is provided as a Reader
Object get(String key)
// Retrieves a value set in the state of this engine.
void put(String key, Object value)
// Sets a key/value pair in the state of the ScriptEngine that may either create a Java Language Binding to be used in the execution of scripts or be used in some other way, depending on whether the key is reserved.
|
eval函数可以用来执行任意的脚本语言代码(从字符串或者文件中)。从变量定义到函数声明、函数调用都是可以的。并且在字符串中也支持使用换行符\n来写多行语句。
get函数用来获取lua中所定义的外部变量的值。通常用来从脚本语言向java返回计算结果。
put函数用来在java中向脚本语言中传递值,put一个值就相当于在脚本语言中创建了一个对应的变量。(可以传递java对象)
执行上下文
在脚本语言执行时,有一个执行环境或者叫执行上下文环境的概念。在默认情况下,脚本引擎会自动创建出一个上下文环境出来。
这样,所有的eval、get、put函数执行的操作都是在同一个上下文中进行的。可以连续多次的执行eval函数。例如:在第一个eval中定义一些函数和变量,在后面的eval中来使用它们。get和put函数也是同样的道理。
如果想要切换上下文环境,在ScriptEngine中也提供了相应的函数,这里就不多做介绍了。
2.3 常用的交互操作
直接用代码来演示比较直观:
读取脚本中的变量
代码:
| e.eval("a = 1 + 1");
Object a = e.get("a");
System.out.println("a = " + a);
|
运行结果:
设定脚本中的变量
代码:
| e.eval("a = 1 + 1");
e.eval("print('a = ' .. a)");
e.put("a", 100);
e.eval("print('a = ' .. a)");
|
运行结果:
调用lua中的函数
代码:
| // 先定义一个lua函数,带有两个参数
e.eval("function sayHello(str, num)\n" +
"print('hello, this is a lua function. p1 = ' .. str .. ', p2 = ' .. num)" +
"end");
// 在java代码中调用此函数
e.eval("sayHello('这是第一个参数', 2222)");
|
运行结果:
| hello, this is a lua function. p1 = 这是第一个参数, p2 = 2222
|
调用java中的函数
代码:
1
2
3
4
5
6
7
8
9
10
11
12 | // 先定义一个java函数,这个方法一定要是`static`的,否则不能调用
public class MyJavaApi {
public static void javaSayHello(String str, int num) {
System.out.println("这是一个Java程序。p1 = " + str + ", p2 = " + num);
}
}
// 调用此函数
e.put("MyJavaApi", new MyJavaApi());
e.eval("MyJavaApi:javaSayHello('这是个字符串参数', 2333)");
|
运行结果:
| 这是一个Java程序。p1 = 这是个字符串参数, p2 = 2333
|
执行脚本文件
代码:
| -- 先定义一个lua脚本文件(在Maven的资源文件夹下面: lua/test.lua)
function func1()
print("this is a lua file.")
end
|
| // 然后在java中执行这个脚本文件,并且调用里面的方法:
// 读取文件
InputStream inputStream = App.class
.getClassLoader().getResourceAsStream("lua/test.lua");
InputStreamReader reader = new InputStreamReader(inputStream);
// 执行脚本文件
e.eval(reader);
// 执行函数
e.eval("func1()");
|
运行结果: