给 Java SE 注入脚本语言的活力

欢迎进入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]

生活中若没有朋友,就像生活中没有阳光一样

给 Java SE 注入脚本语言的活力

相关文章:

你感兴趣的文章:

标签云: