欢迎进入Java社区论坛,与200万技术人员互动交流 >>进入
支持的脚本语言
在dev.java.net可以找到官方的脚本引擎的实现项目。这一项目基于BSD License ,表示这些脚本引擎的使用将十分自由。目前该项目已对包括 Groovy, JavaScript, Python, Ruby, PHP 在内的二十多种脚本语言提供了支持。这一支持列表还将不断扩大。
在 Mustang 中对脚本引擎的检索使用了工厂模式。首先需要实例化一个工厂 ―― ScriptEngineManager。
// create a script engine managerScriptEngineManager factory = new ScriptEngineManager();
ScriptEngineManager 将在 Thread Context ClassLoader 的 Classpath 中根据 jar 文件的 META-INF 来查找可用的脚本引擎。它提供了 3 种方法来检索脚本引擎:
// create engine by nameScriptEngine engine = factory.getEngineByName ("JavaScript");// create engine by nameScriptEngine engine = factory.getEngineByExtension ("js");// create engine by nameScriptEngine engine = factory.getEngineByMimeType ("application/javascript");
下面的代码将会打印出当前的 JDK 所支持的所有脚本引擎
ScriptEngineManager factory = new ScriptEngineManager();for (ScriptEngineFactory available : factory.getEngineFactories()) { System.out.println(available.getEngineName());}
以下各章节代码将以 JavaScript 为例。
在 Java 中解释脚本
有了脚本引擎实例就可以很方便的执行脚本语言,按照惯例,我们还是从一个简单的 Hello World 开始:
public class RunJavaScript { public static void main(String[] args){ ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName ("JavaScript"); engine.eval("print('Hello World')"); }}
这段 Java 代码将会执行 JavaScript 并打印出 Hello World。如果 JavaScript 有语法错误将会如何?
engine.eval("if(true){println ('hello')");故意没有加上”}”,执行这段代码 Java 将会抛出一个 javax.script.ScriptException 并准确的打印出错信息:
Exception in thread "main" javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: missing } in compound statement (<Unknown source>#1) in <Unknown source> at line number 1at ...
如果我们要解释一些更复杂的脚本语言,或者想在运行时改变该脚本该如何做呢?脚本引擎支持一个重载的 eval 方法,它可以从一个 Reader 读入所需的脚本:
ScriptEngineManager factory = new ScriptEngineManager();ScriptEngine engine = factory.getEngineByName ("JavaScript");engine.eval(new Reader("HelloWorld.js"));如此这段 Java 代码将在运行时动态的寻找 HelloWorld.js 并执行,用户可以随时通过改变这一脚本文件来改变 Java 代码的行为。做一个简单的实验,Java 代码如下:
public class RunJavaScript { public static void main(String[] args) throws FileNotFoundException, ScriptException, InterruptedException { ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName ("JavaScript"); while (true) { engine.eval(new FileReader("HelloWorld.js")); Thread.sleep(1000); } }}
HelloWorld.js 内容为简单的打印一个 Hello World: print(‘Hello World’);
运行 RunJavaScript 将会每一秒钟打印一个 Hello World。这时候修改 HelloWorld.js 内容为 print(‘Hello Tony’);
打印的内容将变为 Hello Tony,由此可见 Java 程序将动态的去读取脚本文件并解释执行。对于这一简单的 Hello World 脚本来说,IO 操作将比直接执行脚本损失 20% 左右的性能(在我的 Think Pad 上),但他带来的灵活性――在运行时动态改变代码的能力,在某些场合是十分激动人心的。
[1][2][3][4][5]
生活中若没有朋友,就像生活中没有阳光一样