早在上学期的时候就知道了有这么一个可以执行代码的东西。当时Java的程序设计中有一道题就是让写一个计算机的界面和实现(主要是考GUI),记得当时是写了很繁琐(但是功能很少)的实现代码,基本就是计算“1+1”这种,不能有括号。有同学用了算法(名字忘了,是用来比较复杂的算式的,要用到逆波兰式)。
检查作业那天,因为结束的比较早,也没什么事,就留在机房听别人跟老师唠嗑。老师提到了计算器这件事,他说很多人偏离了题目的考察方向,其实计算结果这部分根本不需要我们自己去实现,有现成的函数,还提到了eval函数。我比较懒,再加上考试也不考,就没去深究,仅是记住有这么一个东西。前几天在做数据库(简直不能叫数据库)的时候,用处理SQL语句中where部分,要是自己处理那就太麻烦了,纠结了几天,突然想到了eval。
上网搜索一番,找到了示例代码,改改之后就移植到我的程序上了。
Eval函数是由scriptEngine类库提供,可以直接执行(脚本语言的)代码(不仅仅是计算算术表达式结果),这一特性在Java6 中加入。据我所研究,目前scriptEngine只能支持javascript语句,据说提供了一些接口,可以很容易的加入解析其他脚本语言的功能。(对牛人来说)
以下是测试通过的示例代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import java.util.*; import java.util.logging.*; import javax.script.*;
public class TestScriptEngine {
public static void main(String[] args) { ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("js"); String query = "1==2 && 'asd'!='dsa'"; long s = System.currentTimeMillis(); try { String res = scriptEngine.eval(query) + ""; System.out.println("The result is: " + res); } catch (ScriptException ex) { Logger.getLogger(TestScriptEngine.class.getName()).log(Level.SEVERE, null, ex); }
long e = System.currentTimeMillis(); System.out.println("Time costs: " + (e - s)); }
public static int test() { ScriptEngineManager manager = new ScriptEngineManager(); List<ScriptEngineFactory> factories = (List<ScriptEngineFactory>)manager.getEngineFactories(); for (ScriptEngineFactory factory : factories) { System.out.printf("Name: %s%n" + "Version: %s%n" + "Language name: %s%n" + "Language version: %s%n" + "Extensions: %s%n" + "Mime types: %s%n" + "Names: %s%n", factory.getEngineName(), factory.getEngineVersion(), factory.getLanguageName(), factory.getLanguageVersion(), factory.getExtensions(), factory.getMimeTypes(), factory.getNames() );
ScriptEngine engine = factory.getScriptEngine(); } return 0; } }
|
结果:
1 2
| The result is: false Time costs: 16
|
注意,如果是需要进行大量的eval操作,先创建ScriptEngine,所有eval共用同一个对象,因为new的过程还是比较耗费时间的。
参考
java ScriptEngine 使用
ScriptEngine (Java Platform SE 8 )