java中使用动态语言

lrxcmwy 2012-11-05

jdk6增加了对动态语言的支持,我觉得他的原理就是把动态语言也编译成JVM可以理解的JAVA字节码的形式来执行的。主要支持的有javascript,ruby,php,python等

这样就可以利用脚本语言的动态特性。

下面是对javascript支持的几个例子。

第1个:

Java代码

importjava.util.logging.Level;

importjava.util.logging.Logger;

importjavax.script.Invocable;

importjavax.script.ScriptEngine;

importjavax.script.ScriptEngineManager;

importjavax.script.ScriptException;

publicclassHelloScript{

publicstaticvoidmain(String[]args){

例子比较简单,就是打印helloword,重要的几个类:

写道

ScriptEngineManagerfactory=newScriptEngineManager();

ScriptEngineengine=factory.getEngineByName("JavaScript");

Java代码

try{

engine.eval("print('helloword')");

}catch(ScriptExceptionex){

Logger.getLogger(HelloScript.class.getName()).log(Level.SEVERE,null,ex);

}

}

}

第二个:

java调用脚本语言的方法

Java代码

importjava.util.logging.Level;

importjava.util.logging.Logger;

importjavax.script.Invocable;

importjavax.script.ScriptEngine;

importjavax.script.ScriptEngineManager;

importjavax.script.ScriptException;

publicclassTestJsFun{

publicstaticvoidmain(String[]args){

ScriptEngineManagerfactory=newScriptEngineManager();

ScriptEngineengine=factory.getEngineByName("JavaScript");

try{

Stringscript="functionhello(name){return'Hello'+name}";

engine.eval(script);

javax.script.Invocableinv=(Invocable)engine;

try{

Stringres=(String)inv.invokeFunction("hello","chenhua");

System.out.println(res);

}catch(NoSuchMethodExceptionex){

Logger.getLogger(HelloScript.class.getName()).log(Level.SEVERE,null,ex);

}

}catch(ScriptExceptionex){

Logger.getLogger(HelloScript.class.getName()).log(Level.SEVERE,null,ex);

}

}

}

脚本引擎本身并不负责执行在脚本中定义的方法,而是转换为javax.script.Invocable 的对象ivh,有ivh的方法invokeFunction()方法来调用脚本的方法。invokeFunction()方法的第一个参数必须是方法名。后面是参数列表。

第三个例子:脚本语言用java的变量

Java代码

importjava.io.File;

importjava.io.IOException;

importjava.util.logging.Level;

importjava.util.logging.Logger;

importjavax.script.ScriptEngine;

importjavax.script.ScriptEngineManager;

importjavax.script.ScriptException;

publicclassTestScriptVariables{

publicstaticvoidmain(String[]args){

ScriptEngineManagerfactory=newScriptEngineManager();

ScriptEngineengine=factory.getEngineByName("JavaScript");

testScript(engine);

}

publicstaticvoidtestScript(ScriptEngineengine){

Filefile=newFile("F:\\test.txt");

if(!file.exists()){

try{

file.createNewFile();

}catch(IOExceptionex){

Logger.getLogger(TestScriptVariables.class.getName()).log(Level.SEVERE,null,ex);

}

}

engine.put("f",file);

try{

engine.eval("println('filesize:'+f.length())");

}catch(ScriptExceptionex){

Logger.getLogger(TestScriptVariables.class.getName()).log(Level.SEVERE,null,ex);

}

}

}

通过写道

engine.put("f",file);

来设置一个全局的变量。这个API比较重要

这样就取到了文件的大小。

第4个例子

脚本语言适用java的类库

Java代码

importjavax.script.Invocable;

importjavax.script.ScriptEngine;

importjavax.script.ScriptEngineManager;

importjavax.script.ScriptException;

publicclassTestUsingJdkClass{

publicstaticvoidmain(String[]args)throwsScriptException,NoSuchMethodException{

ScriptEngineManagerfactory=newScriptEngineManager();

ScriptEngineengine=factory.getEngineByName("JavaScript");

testScript(engine);

}

publicstaticvoidtestScript(ScriptEngineengine)throwsScriptException,NoSuchMethodException{

Stringjs="functiondoSwing(t){varf=newPackages.javax.swing.JFrame(t);f.setSize(400,300);f.setVisible(true);}";

engine.eval(js);

javax.script.Invocableinv=(Invocable)engine;

inv.invokeFunction("doSwing","fromjavascriptswingwindow");

}

}

在脚本中使用了Packages这一个全局变量,专门用于访问java的类库,程序运行后,会出现javaSwing的一个窗体

看截图

最后一个例子:脚本语言实现java的接口

Java代码

importjavax.script.Invocable;

importjavax.script.ScriptEngine;

importjavax.script.ScriptEngineManager;

importjavax.script.ScriptException;

publicclassTestScriptInterface{

publicstaticvoidmain(String[]args)throwsScriptException,NoSuchMethodException{

ScriptEngineManagerfactory=newScriptEngineManager();

ScriptEngineengine=factory.getEngineByName("JavaScript");

testScript(engine);

}

publicstaticvoidtestScript(ScriptEngineengine)throwsScriptException,NoSuchMethodException{

Stringscript="varobj=newObject();obj.run=function(){println('run()wascalled');}";

engine.eval(script);

Objectobj=engine.get("obj");

javax.script.Invocableinv=(Invocable)engine;

Runnabler=inv.getInterface(obj,Runnable.class);

Threadt=newThread(r);

t.start();

}

}

这里通过这句:

Objectobj=engine.get("obj");

来获得脚本中的变量。

然后在通过ivh的getIntegerface()方法转化为java的接口。最后启动一个线程来执行它。

另外:在jdk6中有一个命令行工具:jrunscript

进入bin目录,下面可以运行的,默认为javascript语言,这个可以用来测试我们写的脚本是否正确

------------------java调用perl脚本-----------------------

perl-Java调用perl

Java调用perl

Java代码

Runtime.getRuntime().exec("perlC:\\Perl\\execise.pl");

Java调用perl通过IO的方式来得到返回值

Java代码

packagefiveGame;

importjava.io.BufferedReader;

importjava.io.IOException;

importjava.io.InputStream;

importjava.io.InputStreamReader;

publicclassJavaCallPerl{

publicstaticvoidmain(String[]args)throwsIOException{

StringBufferresultStringBuffer=newStringBuffer();

StringlineToRead="";

intexitValue=0;

try{

Processproc=Runtime.getRuntime().exec("perlC:\\Perl\\execise.pl");

InputStreaminputStream=proc.getInputStream();

BufferedReaderbufferedRreader=newBufferedReader(newInputStreamReader(inputStream));

//savefirstline

if((lineToRead=bufferedRreader.readLine())!=null){

resultStringBuffer.append(lineToRead);

}

//savenextlines

while((lineToRead=bufferedRreader.readLine())!=null){

resultStringBuffer.append("\r\n");

resultStringBuffer.append(lineToRead);

}

//AlwaysreadingSTDOUTfirst,thenSTDERR,exitValuelast

proc.waitFor();//waitforreadingSTDOUTandSTDERRover

exitValue=proc.exitValue();

}catch(Exceptionex){

resultStringBuffer=newStringBuffer("");

exitValue=2;

}

System.out.println("exit:"+exitValue);

System.out.println(resultStringBuffer.toString());

}

}

perl

Java代码

#!/usr/bin/perl-w

$pi=3.141592654;

$circ=2*$pi*12.5;

print"Thecircumferenceofacircleofradius12.5is$circ.\n";

相关推荐