网站首页 > java教程 正文
前言
今天来聊一下java中一个好玩的东西,为什么个人任务好玩呢,举个例子,如果让你实现一个简单四则运算的计算器功能,你需要用多少代码去实现?是不是第一反应就是解析运算表达式,然后分析四则运算规则,再逐一计算得到最后的结果,想着想着,感觉代码就跟止不住了一样,一时半会收不了手,下面,笔者要说的是:5行以内搞定问题,不信你往下看!
Java 平台的脚本引擎
从小标题可以看出,正是这个“玩意”,能让你眼前一亮,先不急着上代码,调调胃口。大家最熟悉的脚本估计应该是js了吧,要知道,js也是可以在java中调用的。既然提及这个“脚本引擎”,那么就从其相关概念开始说起,先给大家展示一下java平台支持哪些脚本引擎,如图:
什么是脚本引擎,如何获取脚本引擎
脚本引擎是一个可以执行用某种特定语言编写的脚本的类库。当虚拟机启动时,它会发现可用的脚本引擎。为了使用他们,我们需要先构造一个ScriptEngineManager,然后通过引擎名、MIME类型或者文件扩展来请求它。来吧,你们最想看的代码来了(代码中包含了运行结果,对照着看比较直观):
如上图所示,没接触过这玩意的程序员们是不是开始亢奋了!代码以js引擎为例,下面我来解释一下图中的基础用法(虽然代码上我标记了注释)。
首先,看下我们的“计算器”的实现逻辑(主要分三步):
- 构造脚本引擎,创建了ScriptEngineManager;
- 指定使用的引擎,代码中以getEngineName方法进行指定;
- 使用引擎调用脚本(执行eval方法),得到最终结果。
需要注意的是,第2步中,除了指定名字的方法外,我们还可以通过两外两种方法指定引擎:
//指定MIME类型
ScriptEngine getEngineByMimeType(String mimeType);
//指定脚本文件拓展名
ScriptEngine getEngineByExtension(String extension);
其次,我们看下如何进行脚本的赋值和绑定(前图代码已展示):
- 赋值,跟写js一样,给变量直接赋值(如n=2);
- 绑定,使用put方法向引擎中添加新的变量绑定;
- 获取变量值,对于赋值和绑定的变量,我们可以使用get方法进行获取变量值。
好了,到这里想必大家已经了解这个引擎平台的强大了吧,但是,如果你以为这样就结束了,那么后面可要睁大眼睛了,它还远不止这些,继续往下看吧。
调用脚本的函数和方法
提供这种功能的脚本引擎实现了Invocable接口,先不说大道理,直接上代码比较直观和容易理解:
如上图所示,脚本直接定义了一个function,然后通过引擎直接输出function的执行结果。这个带来的好处是什么呢?我们可以调用支持的脚本语言的函数,而不必对实际的脚本代码进行计算和解析,从而达到让程序员可以使用脚本语言来实现服务的目的。
这里着重强调invokeFunction方法:
((Invocable)engine).invokeFunction(String arg0, Object... arg1);
接着看,我们还可以更进一步,让脚本引擎去实现一个java接口,然后就可以用java方法调用的语法来调用脚本函数了,不多说,看代码吧:
这里重点强调下getInterface方法,源码中以抽象接口定义,如下:
public abstract <T> T getInterface(Class<T> paramClass);
最后来个锦上添花,引擎还能编译脚本!
由于某些脚本引擎处于对执行效率的考虑,可以将脚本代码编译为某种中间格式,这些引擎实现Compilable接口,还是直接展示代码:
如上图所示,一旦脚本被编译了就执行它(如果引擎不支持编译,就执行原始脚本,如else语句所示)。这种编译脚本的功能适用于需要重复执行的情况。
好了,本篇就到这里,觉得有所收获的就关注一下吧。
猜你喜欢
- 2024-11-13 Java+Redis 通过Lua 完成库存扣减,创建消息队列,异步处理消息
- 2024-11-13 [每日一题][Redis]为什么Lua脚本可以保证原子性?
- 2024-11-13 python脚本查找java类所属jar包(python 调用jar)
- 2024-11-13 Gradle 6.4 RC4 发布,带来 Java 模块、Groovy DSL 脚本插件
- 2024-11-13 Scala声明变量 定义函数 编写脚本
- 2024-11-13 Javacom英文脚本手写字体(java脚本怎么写)
- 2024-11-13 宝藏脚本!Linux系统快速启动Java应用服务,提升开发效率!
- 2024-11-13 分享一个实用脚本——服务器日志清理脚本
- 2024-11-13 Shell编程:命令列表 && 和 ||
- 2024-11-13 SpringBoot进阶——通过Lua脚本批量插入数据到Redis布隆过滤器
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)