天天看點

JDK6新特性

  JDK6增加了對腳本語言的支援(JSR 223),原理上是将腳本語言編譯成bytecode,這樣腳本語言也能享用Java平台的諸多優勢,包括可移植性,安全等,另外,由于現在是編譯成bytecode後再執行,是以比原來邊解釋邊執行效率要高很多。加入對腳本語言的支援後,對Java語言也提供了以下好處。

1、許多腳本語言都有動态特性,比如,你不需要用一個變量之前先聲明它,你可以用一個變量存放完全不同類型的對象,你不需要做強制類型轉換,因為轉換都是自動的。現在Java語言也可以通過對腳本語言的支援間接獲得這種靈活性。

2、 可以用腳本語言快速開發産品原型,因為現在可以Edit-Run,而無需Edit-Compile-Run,當然,因為Java有非常好的IDE支援,我 們完全可以在IDE裡面編輯源檔案,然後點選運作(隐含編譯),以此達到快速開發原型的目的,是以這點好處基本上可以忽略。

3、通過引入腳本語言可以輕松實作Java應用程式的擴充和自定義,我們可以把原來分布在在Java應用程式中的配置邏輯,數學表達式和業務規則提取出來,轉用JavaScript來處理。

Sun的JDK6實作包含了一個基于Mozilla Rhino的 腳本語言引擎,支援JavaScript,這并不是說明JDK6隻支援JavaScript,任何第三方都可以自己實作一個JSR-223相容的腳本引擎使得JDK6支援别的腳本語言,比如,你想讓JDK6支援Ruby,那你可以自己按照JSR 223的規範實作一個Ruby的腳本引擎類,具體一點,你需要實作javax.script.ScriptEngine(簡單起見,可以繼承javax.script.AbstractScriptEngine)和javax.script.ScriptEngineFactory兩個接口。當然,在你實作自己的腳本語言引擎之前,先到scripting.dev.java.net project 這裡看看是不是有人已經幫你做了工作,這樣你就可以直接拿來用就行。

Scripting API

Scripting API是用于在Java裡面編寫腳本語言程式的API, 在Javax.script中可以找到Scripting API,我們就是用這個API來編寫JavaScript程式,這個包裡面有一個ScriptEngineManager類,它是使用Scripting API的入口,ScriptEngineManager可以通過jar服務發現(service discovery)機制尋找合适的腳本引擎類(ScriptEngine),使用Scripting API的最簡單方式隻需下面三步

1、建立一個ScriptEngineManager對象

2、通過ScriptEngineManager獲得ScriptEngine對象

3、用ScriptEngine的eval方法執行腳本

下面是一個Hello World程式

public class HelloScript {

public static void main(String[] args) throws Exception {

        ScriptEngineManager factory = new ScriptEngineManager();//step 1

        ScriptEngine engine = factory.getEngineByName("JavaScript");//Step 2       

 engine.eval("print('Hello, Scripting')");//Step 3

    }   

}

運作上面程式,控制台會輸出

Hello, Scripting

上面這個簡單的Scripting程式示範了如何在Java裡面運作腳本語言,除此之外,我們還可以利用Scripting API實作以下功能

1、暴露Java對象為腳本語言的全局變量

2、在Java中調用腳本語言的方法

3、腳本語言可以實作Java的接口

4、腳本語言可以像Java一樣使用JDK平台下的類

下面的類示範了以上4種功能

package Scripting;

import java.io.File;

import javax.script.Invocable;

import javax.script.ScriptEngine;

import javax.script.ScriptEngineManager;

import javax.script.ScriptException;

public class ScriptingAPITester {

    public static void main(String[] args) throws Exception {

        ScriptEngineManager manager = new ScriptEngineManager();

        ScriptEngine engine = manager.getEngineByName("JavaScript");

        testScriptVariables(engine);//示範如何暴露Java對象為腳本語言的全局變量

         testInvokeScriptMethod(engine);//示範如何在Java中調用腳本語言的方法

         testScriptInterface(engine);//示範腳本語言如何實作Java的接口

         testUsingJDKClasses(engine);//示範腳本語言如何使用JDK平台下的類

    }

    public static void testScriptVariables(ScriptEngine engine) throws ScriptException{

        File file = new File("test.txt");

        engine.put("f", file);

        engine.eval("println('Total Space:'+f.getTotalSpace())");       

    }

    public static void testInvokeScriptMethod(ScriptEngine engine) throws Exception{

        String script = "function hello(name) { return 'Hello,' + name;}";

        engine.eval(script);

        Invocable inv = (Invocable) engine;

        String res = (String)inv.invokeFunction("hello", "Scripting" );

        System.out.println("res:"+res);

    }

    public static void testScriptInterface(ScriptEngine engine) throws ScriptException{

        String script = "var obj = new Object(); obj.run = function() { println('run method called'); }";

        engine.eval(script);

        Object obj = engine.get("obj");

        Invocable inv = (Invocable) engine;

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

        Thread th = new Thread(r);

        th.start();

    }

    public static void testUsingJDKClasses(ScriptEngine engine) throws Exception{

        //Packages是腳本語言裡的一個全局變量,專用于通路JDK的package

        String js = "function doSwing(t){var f=new Packages.javax.swing.JFrame(t);f.setSize(400,300);f.setVisible(true);}";

        engine.eval(js);

        Invocable inv = (Invocable) engine;

        inv.invokeFunction("doSwing", "Scripting Swing" );

    }

}

Scripting Tool

SUN提供的JDK6中有一個指令行工具——jrunscript,你可以在<JDK6_Home>/bin下面找到這個工具,jrunscript是一個腳本語言的解釋程式,它獨立于腳本語言,但預設是用JavaScript,我們可以用jrunscript來測試自己寫的腳本語言是否正确,下面是一個在指令行運作jrunscript的簡單例子

jrunscript

js>println("Hello,JrunScript");

Hello,JrunScript

js>9*8

72.0

js>