JDK6.0里面加了一个很实用的包,javax.script,它是JAVA新增的操作脚本的包,利用它我们可以对脚本语言进行操作,比如修改,或者调用,并且可以和JAVA语言交互,如果我们利用好的话,我们利用它来实现一些经常要改的部份,这样我们就可以把一些算法写到js文件里面,然后再在运行的时候读取出来并执行,这样就省去了更改一些东西需要重新编译的过程了.

下面我们就来看一个例子吧,看看如何在JAVA代码里面操作脚本并调用里面的方法.

/* 
 
  * Test.java
  * 
  * Created on 2007-9-19, 15:28:49
  * 
  * To change this template, choose Tools | Templates
  * and open the template in the editor.
   
 */ 
 

 
 package 
  lbf.script;

 
 import 
  java.io.FileReader;
 
 import 
  java.util.ArrayList;
 
 import 
  java.util.List;
 
 import 
  javax.script.Bindings;
 
 import 
  javax.script.Invocable;
 
 import 
  javax.script.ScriptContext;
 
 import 
  javax.script.ScriptEngine;
 
 import 
  javax.script.ScriptEngineManager;
 
 import 
  javax.swing.JFrame;

 
 /** 
 
  *
  *  
 @author 
  hadeslee
   
 */ 
 
 
 public 
   
 class 
  Test {
     
      
 public 
   
 static 
   
 void 
  main(String[] args) 
 throws 
  Exception {
          
 // 
 根据js的后缀名生成一个解析JS的脚本解析引擎 
 
 
         ScriptEngine engin 
 = 
 new 
  ScriptEngineManager().getEngineByExtension( 
 " 
 js 
 " 
 );
          
 // 
 查询一下这个引擎是否实现了下面很实用的接口 
 
 
         System.out.println(engin  
 instanceof 
  Invocable);
          
 // 
 声明两个对象,传入到JS里面去 
 
 
         JFrame jf 
 = 
 new 
  JFrame( 
 " 
 test 
 " 
 );
         List 
 < 
 String 
 > 
  list 
 = 
 new 
  ArrayList 
 < 
 String 
 > 
 ();
          
 // 
 得到挷定的键值对象,把当前的两个JAVA对象放进去 
 
 
         Bindings bind 
 = 
 engin.createBindings();
         bind.put( 
 " 
 jf 
 " 
 ,jf);
         bind.put( 
 " 
 list 
 " 
 ,list);
          
 // 
 把挷下的键值对象放进去,作用域是当前引擎的范围  
 
 
         engin.setBindings(bind, ScriptContext.ENGINE_SCOPE);
          
 // 
 用引擎执行一段写在JS文件里面的代码 
 
 
         Object obj 
 = 
 engin.eval( 
 new 
  FileReader( 
 " 
 test.js 
 " 
 ));
          
 // 
 这个时候返回值当然 是null了 
 
 
         System.out.println(obj);
          
 // 
 把当前的引擎强制转为Invocable,这样就可以调用定义在JS文件里面的一个一个函数了 
 
 
         Invocable in 
 = 
 (Invocable)engin;
          
 // 
 得到了从JS里面返回来的对象 
 
 
         List 
 < 
 String 
 > 
  l 
 = 
 (List 
 < 
 String 
 > 
 )in.invokeFunction( 
 " 
 getNames 
 " 
 );
         System.out.println(l);
          
 // 
 调用一下定义在JS里面的另一个函数 
 
 
         in.invokeFunction( 
 " 
 testJS 
 " 
 );
          
 // 
 最后调用一个函数,该函数可以使我们前面定义的窗体显示出来 
 
 
         in.invokeFunction( 
 " 
 doSth 
 " 
 );
     }
 }

下面是定义在test.js里面的内容



function 
  doSth(){
         jf.setSize( 
 500 
 , 
 300 
 );
         jf.setVisible( 
 true 
 );
         jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
     }
     
     
      
 function 
  getNames(){
             list.add( 
 " 
 doSth 
 " 
 );
             list.add( 
 " 
 getNames 
 " 
 );
              
 return 
  list;
         }
         
          
 function 
  testJS(){
                 print('Hello world 
 ! 
 ');
             }

我们可以看到,在JAVA运行了以后,窗体会显示出来,并且我们可以接收到从JS解析引擎里面传回的数据,当然我们也可以调用一个很普通的JS函数,想象一下,如果我们把我们程序运行时的一些对象都设到Bindings里面去,那么我们JS岂不是有很大的自由度了吗?因为JS里面也可以操作我们的JAVA对象了,并且我们可以像JAVA编程一样的对JS编程了,还不用再编译,马上就可以运行.灵活性岂不是变得更高了吗?



过几天写一个利用JAVA解析JS提高编程灵活性的例子,以体现一下这个包的用处,不过,JS的缺点就是执行速度慢,比起JAVA代码那是慢多了,但是一些初始化的事情,或者一些设置的事情,我们就不用写死在程序里面了,就可以从我们定义的JS文件里面读取了,毕竟那些只执行一次的方法牺牲一点效率换来很高的灵活度是很值得的.