知识大全 Java SE 6之脚本引擎 让程序如虎添翼
Posted 知
篇首语:与其降低你的开支,不如去尝试增加你的收入。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Java SE 6之脚本引擎 让程序如虎添翼相关的知识,希望对你有一定的参考价值。
Java SE 6之脚本引擎 让程序如虎添翼 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
现在Java SE 已经发布 在明年Java SE 也将发布 Java SE 较Java SE 有了很大的改进 它的功能更强 而且是专为Vista所设计 这就意味着Java SE 将是Vista上的最佳选择 而Java SE 所提供的最众多的新功能必将成为它的最大卖点 Java SE 最引人注目的新功能之一就是内嵌了脚本支持 在默认情况下 Java SE 只支持JavaScript 但这并不以为著Java SE 只能支持JavaScript 在Java SE 中提供了一些接口来定义一个脚本规范 也就是JSR 通过实现这些接口 Java SE 可以支持任意的脚本语言(如PHP或Ruby) 运行第一个脚本程序 在使用Java SE 运行脚本之前 必须要知道你的Java SE 支持什么脚本语言 在javax script包中有很多的类 但这些类中最主要的是ScriptEngineManager 可以通过这个类得到当前Java SE 所支持的所有脚本 如下面例子将列出所有可以使用的脚本引擎工厂 import javax script *;import java io *;import java util *;import static java lang System *;public class ListScriptEngines public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); // 得到所有的脚本引擎工厂 List<ScriptEngineFactory> factories = manager getEngineFactories(); // 这是Java SE 和Java SE 的新For语句语法 for (ScriptEngineFactory factory: factories) // 打印脚本信息 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(); 上面的例子必须要在Java SE 中编译 其中import static java lang System *是新的语法 将System中的所有静态成员进行引用 以后就可以直接使用out in或err了 通过运行java ListScriptEngines 将显示如下信息 Name: Mozilla RhinoVersion: release Language name: ECMAScriptLanguage version: Extensions: [js]Mime types: [application/javascript application/ecmascript text/javascript text/ecmascript]Names: [js rhino JavaScript javascript ECMAScript ecmascript] 在最下面一行是脚本的别名 也就是使用它们中的任意一个都可以 得到一个具体的脚本引擎有 种方法 ·根据扩展名得到脚本引擎 ScriptEngine engine = manager getEngineByExtension( js ); getEngineByExtension的参数就是Extensions:[js]中[…]里的部分 ·根据Mime类型得到脚本引擎 ScriptEngine engine = manager getEngineByMimeType( text/javascript ); getEngineByMimeType的参数可以是Mime types: [application/javascript application/ecmascript text/javascript text/ecmascript]中的任何一个 可以将text/javascript改成text/ecmascript ·根据名称得到脚本引擎 ScriptEngine engine = manager getEngineByName( javascript ); getEngineByName后的参数可以是Names: [js rhino JavaScript javascript ECMAScript ecmascript]中的任何一个 如可以将javascript改成ecmascript 上面已经讨论了执行脚本的第一步 就是得到一个可用的脚本引擎 在完成这项工作之 后就可以利用这个脚本引擎执行相应的脚本了 我们可以使用ScriptEngine的eval方法来执行脚本 eval方法被重载的多次 但最常用的是public Object eval(String script) 下面的例子演示了如何使用eval方法来执行javascript脚本 import javax script *;import java io *;import static java lang System *;public class FirstJavaScript public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); // 得到javascript脚本引擎 ScriptEngine engine = manager getEngineByName( javascript ); try // 开始运行脚本 并返回当前的小时 Double hour = (Double)engine eval( var date = new Date(); + date getHours(); ); String msg; // 将小时转换为问候信息 if (hour < ) msg = 上午好 ; else if (hour < ) msg = 下午好 ; else if (hour < ) msg = 晚上好 ; else msg = 晚安 ; out printf( 小时 %s: %s%n hour msg); catch (ScriptException e) err println(e);上面的例子通过得到当前的小时 并将其转化为问候语 上面的程序的输出信息为 小时 上午好 这个例子最值得注意的是执行的 句脚本 最后一句是date getHours() 并未将这个值赋给一个javascript变量 这时 eval方法就将这样的值返回 这有些类似C语言的(…)运算符 如(c=a+b c + d) 这个表达式的返回值是a+b+d
和脚本语言进行交互 上面例子只是运行了一个非常简单的脚本 这个脚本是孤立的 并未通过Java向这脚本传递任何的值 虽然从这个脚本返回了一个值 但这种返回方式是隐式的 脚本引擎除了这些简单的功能 还为我们提供了更强大的功能 甚至可以通过Java向脚本语言中传递参数 还可以将脚本语言中的变量的值取出来 这些功能要依靠ScriptEngine中的两个方法put和get put 有两个参数 一个是脚本变量名 另一个是变量的值 这个值是Object类型 因此 可以传递任何值 get 有一个参数 就是脚本变量的名 下面的代码通过javascript脚本将一个字符串翻转(这个字符串是通过java传给javascript的) 然后通过java得到这个被翻转后的字符后 然后输出
import javax script *;import java io *;import static java lang System *;public class ReverseString public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); // 建立javascript脚本引擎 ScriptEngine engine = manager getEngineByName( javascript ); try // 将变量name和变量值abcdefg传给javascript脚本 engine put( name abcdefg ); // 开始执行脚本 engine eval( var output = ; + for (i = ; i <= name length; i++) + output = name charAt(i) + output + ); // 得到output变量的值 String name = (String)engine get( output ); out printf( 被翻转后的字符串 %s name); catch (ScriptException e) err println(e);
以上代码的输出结果为 被翻转后的字符串 gfedcba
让脚本运行得更快 众所周知 解释运行方式是最慢的运行方式 上述的几个例子无一例外地都是以解释方式运行的 由于Java EE 的脚本引擎可以支持任何实现脚本引擎接口的语言 有很多这样的语言提供了编译功能 也就是说 在运行脚本之前要先将这些脚本进行编译(这里的编译一般将不是生成可执行文件 而只是在内存中编译成更容易运行的方式) 然后再执行 如果某段脚本要运行之交多次的话 使用这种方式是非常快的 我们可以使用ScriptEngine的pile方法进行编译 并不是所有脚本引擎都支持编译 只有实现了Compilable接口的脚本引擎才可以使用pile进行编译 否则将抛出一个错误 下面的例子将演示如何使用pile方法编译并运行javascript脚本 import javax script *;import java io *;import static java lang System *;public class CompileScript public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager getEngineByName( javascript ); engine put( counter ); // 向javascript传递一个参数 // 判断这个脚本引擎是否支持编译功能 if (engine instanceof Compilable) Compilable pEngine = (Compilable)engine; try // 进行编译 CompiledScript script = pile( function count() + counter = counter + ; + return counter; + ; count(); ); out printf( Counter: %s%n script eval()); out printf( Counter: %s%n script eval()); out printf( Counter: %s%n script eval()); catch (ScriptException e) err println(e); else err println( 这个脚本引擎不支持编译! ); 上面的代码运行后的显示信息如下 Counter: Counter: Counter: 在这个例子中 先通过pile方法将脚本编译 然后通过eval方法多次进行调用 在这段代码中只有一个函数 因此 eval就返回了这个函数的值
动态调用脚本语言的方法 上面的例子只有一个函数 可以通过eval进行调用并将它的值返回 但如果脚本中有多个函数或想通过用户的输入来决定调用哪个函数 这就需要使用invoke方法进行动态调用 和编译一样 脚本引擎必须实现Invocable接口才可以动态调用脚本语言中的方法 下面的例子将演示如何通过动态调用的方式来运行上面的翻转字符串的javascript脚本 import javax script *;import java io *;import static java lang System *;public class InvocableTest public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager getEngineByName( javascript ); if (engine instanceof Invocable) try engine eval( function reverse(name) + var output = ; + for (i = ; i <= name length; i++) + output = name charAt(i) + output + return output; ); Invocable invokeEngine = (Invocable)engine; Object o = invokeEngine invoke( reverse name); out printf( 翻转后的字符串 %s name); catch (NoSuchMethodException e) err println(e); catch (ScriptException e) err println(e); else err println( 这个脚本引擎不支持动态调用 );
动态实现接口 脚本引擎还有一个更吸引的功能 那就是动态实现接口 如我们要想让脚本异步地执行 即通过多线程来执行 那InvokeEngine类必须实现Runnable接口才可以通过Thread启动多线程 因此 可以通过getInterface方法来使InvokeEngine动态地实现Runnable接口 这样一般可分为 步进行 使用javascript编写一个run函数
engine eval( function run() print( 异步执行 ); );
通过getInterface方法实现Runnable接口
Runnable runner = invokeEngine getInterface(Runnable class);
使用Thread类启动多线程
Thread t = new Thread(runner);t start();
下面是实现这个功能的详细代码
import javax script *;import static java lang System *;public class InterfaceTest public static void main(String args[]) ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager getEngineByName( javascript ); try engine eval( function run() print( 异步调用 ); ); Invocable invokeEngine = (Invocable)engine; Runnable runner = invokeEngine getInterface(Runnable class); Thread t = new Thread(runner); t start(); t join(); catch (InterruptedException e) err println(e); catch (ScriptException e) System err println(e);
cha138/Article/program/Java/Javascript/201311/25487相关参考
给JavaSE注入脚本语言的活力 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年月日 
在.NET中使用脚本引擎 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在应用程序中使用脚本引擎
让界面更加绚丽JavaSE6.0四种新功能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 
JavaSE6新特性:JavaDB&n 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
知识大全 Java SE 6 新特性: Instrumentatio
JavaSE6新特性:Instrumentatio 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 Java SE 6中XML数字签名标准Java接口
JavaSE6中XML数字签名标准Java接口 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 级
JavaSE6新特性:HTTP增强 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 摘要 Jav
知识大全 驾驭“野马”-- 探索Java SE 6的一些新特性
驾驭“野马”--探索JavaSE6的一些新特性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! s
JavaSE6新特性:JMX与系统管理 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
JavaSE6新特性:编译器API 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun公司