简单说一下如何再 java 中调用 其他脚本语言(如js)

java的脚本机制

脚本API可以让你在Java平台上运行脚本语言(js,ruby等等)

ScriptEngineManager类效果
getEngineByName(语言名称)通过名称返回ScriptEngine实例
getEngineByExtension(扩展名)通过扩展名返回ScriptEngine实例
getEngineByMimeType(MIME类型)通过MIME返回ScriptEngine实例
getEngineFactories()返回List<ScriptEngineFactory>工厂集合
createBindings()实例化Bindings对象
ScriptEngineFactory类效果
getNames()返回该工厂知道的名字的集合
getExtensions()返回该工厂知道的扩展名的集合
getMimeTypes()返回该工厂知道的MIME类型的集合

你可向ScriptEngineFactory询问该工厂支持的引擎名

ScriptEngineManager manager=new ScriptEngineManager();
List<ScriptEngineFactory> list=manager.getEngineFactories();
ScriptEngineFactory factory=list.get(0);
for(String i:factory.getNames()) {
    System.out.println(i);
}//这段程序的目的是输出第一个工厂支持的名字

一旦你有了引擎后你就可以像这样调用脚本(本文都以js代码做示范):

ScriptEngineManager manager=new ScriptEngineManager();
ScriptEngine engine=manager.getEngineByName("js");//得到js引擎
engine.eval("print(\"这是脚本语言输出的\")");//运行js代码
ScriptEngine类效果
eval(脚本语言代码)可以通过String或者通过Reader类从文件里读入代码来执行,也会返回一个Object值
eval(脚本语言代码,bindings对象)同上,但指定一个Bindings
put(变量名,值)绑定一个变量的值
get(“变量名”)得到一个变量的值
getContext()返回Context对象

可以在一个引擎上调用多个脚本,如下所示,我们先定义一个变量,再进行计算,得到返回值

engine.eval("n=66");//定义n变量
Object num=engine.eval("n+1");返回n+1的值
System.out.print(num);

我们也可以这样绑定变量(变量值可以是java对象):

engine.put("n",66);//绑定n变量
Object num=engine.eval("n+1");返回n+1的值
System.out.print(num);

作用域

除了引擎作用域,任何添加到ScriptEngineManager的绑定对所有引擎可见(即全局作用域)。

除了这些外,还可以将变量绑定到Bindings对象中,然后将其传到eval中:

Bindings b=engine.createBindings();//实例化Bindings
b.put("n", 66);
Object num=engine.eval("n+1",b);
System.out.print(num);//输出67
BIndings类
put(变量名,值)绑定变量
get(变量名)得到变量

重定向输入输出

可以重定向脚本的标准输入输出。如js里的print和println,其他的输出不管

Writer pw=new PrintWriter("D:1.txt","UTF-8");//指定输出位置和编码格式
engine.getContext().setWriter(pw);
engine.eval("print(\"啦啦啦\")");//打印在1.txt文件里
Context类效果
getReader()和setReader(Reader)得到或设置 脚本的标准输入 位置
getWriter()和setWriter(Reader)得到或设置 脚本的标准输出 位置
getErrorWriter()和setErrorWriter(Reader)得到或设置 脚本的标准错误输出 位置

调用脚本的函数和方法

我们可以调用脚本语言里的函数。提供这些功能的脚本引擎要实现 Invocable接口,如js脚本引擎。

ScriptEngine engine=new ScriptEngineManager().getEngineByName("JavaScript");
//在js里定义一个p函数
engine.eval("function p(str){return 'hello '+str+'!'}");
//获得一个Invocable接口的对象
Invocable invocable=(Invocable)engine;
Object result=invocable.invokeFunction("p","shit");//调用js的函数
        System.out.print(result);

如果脚本语言是面向对象的,那还可以调用 对象里的方法

//在js中定义Girl类 
engine.eval("function Girl(str){this.jk=str}");
engine.eval("Girl.prototype.f1="+"function(str){return this.jk+str}");
//实例化girl对象
Object girl=engine.eval("new Girl(\"jk美少女\")");
//调用girl对象里的f1方法
Object result=((Invocable)engine).invokeMethod(girl,"f1","是我");
    System.out.print(result);//输出结果为jk美少女是我
Invocable接口效果
invokeFunction(方法名,参数......)调用 脚本的函数
invokeMethod(对象,方法名,参数.....)调用 脚本对象的方法
getInterface(Class对象)返回指定的类的对象

在js中,如果定义了相同名字的函数,那么可以通过这个接口来调用它。相当于得到了实现了这个接口的一个对象

public interface Hello{
    String hello(String str);
}//这是在Java里编写的Hello接口
//————————————————————————————————————
//在js里实现Hello接口
engine.eval("function hello(str){return str+\",hello\"}");
Hello h=((Invocable)engine).getInterface(Hello.class);
System.out.print(h.hello("wrold"));

编译脚本

某些时候处于效率考虑,会先把脚本代码编译为中间格式,再来使用:

CompiledScript script=((Compilable)engine).compile("print(123)");
script.eval();
Compilable接口
compile(字符串代码)返回编译了的CompiledScript对象
compile(Reader对象)同上
CompiledScript类
eval()执行编译好了的代码
eval(Bindings对象)同上,但加上Bindings对象里的变量
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值