国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

為Java創(chuàng)建你自己的腳本語言-JSR 223介紹

瀏覽:101日期:2024-06-05 15:10:43
內(nèi)容: 摘要即將發(fā)布的Java6.0包含了Java平臺腳本(JSR 223)的實現(xiàn)。這個JSR關(guān)注于程序設(shè)計語言以及他們與Java的整合。本文通過一個簡單的“Boolean語言的實現(xiàn)展示了JSR 223的能力和潛力。通過這個例子,你將看到如何使用Scripting API(javax.script.*)編寫程序,如何打包并發(fā)布一個符合腳本引擎發(fā)現(xiàn)機制的語言實現(xiàn),以及如何使你的腳本引擎對JSR 223是可編譯和可調(diào)用的。在Java平臺腳本(JSR 223)——以及他的前任BSF(Bean Scripting Framework)——之前,已經(jīng)有很多種語言可以與Java交互。其中一些可以接受一段Java程序的文本代碼作為輸入,然后將代碼的執(zhí)行結(jié)果返回給Java程序。而另外一些可以保持Java程序里的對象的引用,并可以執(zhí)行這個對象的方法,或者創(chuàng)建一個新的Java Class的實例。由于每個語言都有自己的與Java交互的方法,開發(fā)人員如果想要在他們的Java程序中使用腳本引擎就必須學(xué)習(xí)每個腳本引擎特殊的編程接口。為了解決這個問題,JSR 223定義了一個約定,所有遵循這個規(guī)范的腳本引擎都必須遵守這個約定。這個約定由一組Java接口和類、以及一個打包和部署腳本引擎的機制組成。當(dāng)使用遵循JSR 223的腳本引擎時,只需要使用標(biāo)準(zhǔn)定義的一組接口。由于腳本引擎的具體實現(xiàn)會被良好地封裝,你根本不需要考慮他們。JSR 223不僅使腳本引擎使用更簡單,而且也使腳本引擎的開發(fā)更簡單。如果你設(shè)計實現(xiàn)了一個程序語言,只需要實現(xiàn)JSR 223的接口來包裝(wrap)你的腳本引擎,就可以使你的腳本引擎更容易使用并擁有更多的使用者。在我們看JSR 223的接口和本文對他們的實現(xiàn)之前,我先要指出:雖然JSR 223的名稱和本文的標(biāo)題里都含有“腳本這個詞,但是并不意味著會限制在可以使用JSR 223進行整合的語言。你可以使用任何你喜歡的語言,并且用一個遵守JSR 223約定的層包裝它。這個語言可以是面向?qū)ο蟮摹⒑瘮?shù)的、或者符合任何編程范型的程序語言。他可以是強類型、弱類型或者根本沒有類型限制。事實上,在寫這篇文章前,我已經(jīng)為Scheme(一個弱類型的函數(shù)程序語言)實現(xiàn)了一個遵循JSR 223的包裝器,并已經(jīng)放到了SourceForge上。在這篇文章里,我們使用一個更簡單的語言,這樣我們就可以集中精力于JSR 223,而不用費神于語言的細(xì)節(jié)。不用擔(dān)心你是否有自己創(chuàng)建一個程序語言的經(jīng)歷。這篇文章不討論程序語言,只是討論JSR 223定義的程序語言和Java之間需要遵循的約定。版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時請務(wù)必保留以下作者信息和鏈接作者:Chaur Wu;niuji原文:http://www.javaworld.com/javaworld/jw-04-2006/jw-0424-scripting.htmlMatrix:http://www.matrix.org.cn/resource/article/44/44604_JSR+223.html關(guān)鍵字:JSR 223BoolScript引擎圖一顯示了我們的示例的各個部分以及他們是如何相互關(guān)聯(lián)的。這篇文章里的示例定義了一個簡單的語言,我稱之為BoolScript。我稱編譯執(zhí)行BoolScript代碼的程序為BoolScript引擎。除了編譯和執(zhí)行BoolScript代碼,BoolScript引擎還實現(xiàn)了JSR 223的約定,是一個符合JSR 223規(guī)范的腳本引擎。如圖所示,Boolscript引擎的代碼打包在boolscript.jar中。 圖一:BoolScript概覽。在這篇文章里,當(dāng)我提到JSR 223時都是指JSR 223的規(guī)范,JSR 223框架就是指這個規(guī)范的實現(xiàn)。這篇文章里使用的JSR 223框架已經(jīng)包含于Java Standard Edition 6.0中(Java SE是sun的J2SE新名字)。我們的例子里包含了一個使用BoolScript引擎的Java程序,代碼詳見BoolScriptHostApp.java文件。注意圖一展示了Java程序總是通過JSR 223框架間接的和腳本引擎打交道。你需要Java SE 6.0 beta和這篇文章的二進制文件來運行這個示例。我使用的Java SE 6.0的版本是build 77。你可以在java.net下載,你也可以使用Sun Developer Network提供的Java SE 6.0。示例代碼在資源中提供下載,其中包含了以下文件:+BoolScriptEngine-Source.zip BoolScript引擎的源代碼+BoolScriptHostExample-Source.zip Java示例程序源代碼+BoolScriptHostExample.zip BoolScript引擎和Java示例程序的二進制代碼示例程序是BoolScriptHostExample.zip 中的BoolScriptHostApp.class ,解壓縮到任意文件夾執(zhí)行即可。這個zip文件里還包含了3個jar文件,執(zhí)行時需要將他們加到Java的classpath中。具體可參照run.bat文件里的代碼,這個文件也包含在BoolScriptHostExample.zip 文件里。示例執(zhí)行產(chǎn)生如下輸出: Mozilla RhinoBool Script Engineanswer of boolean expression is: falseanswer of boolean expression is: trueanswer of boolean expression is: false BoolScript 語言在深入JSR 223的細(xì)節(jié)前,我們先快速地了解一下BoolScript語言。BoolScript非常簡單,他唯一能做的就是計算布爾表達式的值。下面是BoolScript代碼的例子:(True | False) & True(True & x) | y可以看到,BoolScript支持兩個操作符:&(邏輯與)和|(邏輯或)。BoolScript還支持三個操作數(shù):True、False和變量,變量的值只能是True或False。腳本引擎發(fā)現(xiàn)機制為了看清楚JSR 223框架在Java程序和腳本引擎間做了哪些工作,我們先假設(shè)你想要在你的程序里使用一個腳本引擎。首先,你需要創(chuàng)建腳本引擎的實例;然后,需要將腳本代碼傳給引擎,讓引擎求值(或者編譯這段腳本代碼供以后執(zhí)行)。我們仔細(xì)看下這些步驟,記住:不論我們做什么,我們只能通過JSR 223框架使用腳本。創(chuàng)建腳本引擎的實例前我們首先要創(chuàng)建javax.script.ScriptEngineManager的實例,然后用這個實例查詢腳本引擎的實例。你可以根據(jù)腳本引擎的名字、MIME類型或文件擴展名查詢引擎實例。例如我們的BoolScript代碼保存文件是*.bool,那么文件擴展名就是bool。下面的代碼演示了如何使用擴展名查詢腳本引擎實例。ScriptEngineManager engineMgr = new ScriptEngineManager();ScriptEngine bsEngine = engineMgr.getEngineByExtension('bool');但是我們在哪指定我們的腳本引擎的名稱、MIME類型和文件擴展名呢?我們使用了BoolScriptEngineFactory類來指定這些屬性。這個類實現(xiàn)了javax.script.ScriptEngineFactory接口的getExtensions()、getMimeTypes()、和 getNames()方法。我們在這幾個方法里聲明了BoolScript引擎的名稱、MIME類型和文件擴展名。下面是BoolScriptEngineFactory的getExtensions()方法:public List getExtensions() { ArrayList extList = new ArrayList(); extList.add('bool'); return extList;}你可能會奇怪為什么使用ScriptEngineManager創(chuàng)建BoolScriptEngine的實例,而不是用下面的方法直接創(chuàng)建:ScriptEngine bsEngine = new BoolScriptEngine();當(dāng)然,你可以用這種方法創(chuàng)建。事實上,我在開發(fā)示例代碼的時候為了測試也這樣使用過。直接創(chuàng)建腳本引擎實例在測試的時候是可以的,但在實際運行環(huán)境中,這樣做違反了必須通過JSR 223框架操作腳本引擎的規(guī)定,破壞了JSR 223隱藏腳本引擎信息的目的。JSR 223通過使用工廠方法(Factory Method)模式隱藏腳本引擎的詳細(xì)信息,從而達到將腳本引擎從Java程序中解耦的目的。直接創(chuàng)建腳本引擎的另一個問題是略過了ScriptEngineManager可能會對腳本引擎實例做的初始化工作。接下來我們就會看到ScriptEngineManager做的這種工作。ScriptEngineManager是如何根據(jù)bool查找BoolScriptEngine并創(chuàng)建他的實例的呢?答案就是JSR 223里的腳本引擎發(fā)現(xiàn)機制。在后面對這個機制的討論過程中,你將看到ScriptEngineManager會對腳本引擎做哪些初始化工作,還有他為什么要做這些工作。根據(jù)腳本引擎發(fā)現(xiàn)機制,一個腳本引擎的提供者在打包腳本引擎實現(xiàn)的類文件的時候還需要打包一個附加的文件到j(luò)ar文件中。這個文件必須放在jar文件的META-INF/services目錄下面,而且名稱必須是javax.script.ScriptEngineFactory。打開boolcripts.jar你就可以看到這樣的目錄結(jié)構(gòu)。文件META-INF/services/javax.script.ScriptEngineFactory的內(nèi)容必須包含實現(xiàn)了ScriptEngineFactory的類的全名。在我們的例子中只有一個這樣的類,我們文件內(nèi)容如下:net.sf.model4lang.boolscript.engine.BoolScriptEngineFactory當(dāng)一個腳本引擎提供者將他/她的腳本引擎打包成jar文件并發(fā)布后,用戶只需要將這個jar文件放入Java的classpath里就可以完成安裝。圖二展示了Java程序通過JSR 223框架發(fā)現(xiàn)腳步引擎時發(fā)生的事件。 圖二 Java程序如何發(fā)現(xiàn)腳本引擎當(dāng)使用名字、MIME類型或文件擴展名查詢指定的腳本引擎時,ScriptEngineManager將遍歷classpath中所有的的ScriptEngineFactory類。如果找到符合的,ScriptEngineManager就會創(chuàng)建這個引擎工廠的實例,然后用這個工廠實例創(chuàng)建腳本引擎的實例。腳本引擎工廠使用getScriptEngine()創(chuàng)建腳本引擎,腳本引擎提供者需要實現(xiàn)這個方法。你可以看下BoolScriptEngineFactory的代碼,其中g(shù)etScriptEngine()的實現(xiàn)如下:public ScriptEngine getScriptEngine() { return new BoolScriptEngine();}這個方法很簡單,只是創(chuàng)建了一個腳本引擎的實例并將這個實例返回給ScriptEngineManager(或者任何調(diào)用這個方法的類)。我們感興趣的是在ScriptEngineManager得到這個實例后,在將這個實例返回給Java程序前,ScriptEngineManager為了初始化這個引擎而調(diào)用的setBindings()方法。這時我們需要了解JSR 223的一個核心概念:Java綁定。在我解釋了綁定、范圍和上下文的概念和構(gòu)造后,你就能明白setBindings()為腳本引擎做了哪些初始化工作。綁定、范圍、上下文回憶下,BoolScript語言允許使用下面的代碼:(True & x) | y但是他未提供任何構(gòu)造讓你給變量x、y賦值。我應(yīng)該將語言設(shè)計成可以使用如下的代碼:x = Truey = False(True & x) | y但是我是故意忽略了賦值操作符=,使BoolScript代碼必須在包含定義了變量的值的上下文中執(zhí)行。這意味著當(dāng)Java程序用BoolScript腳本引擎計算一段文本代碼的值時,同時需要將一個上下文提供給腳步引擎,或者至少要讓腳本引擎知道需要使用哪個上下文。你可以認(rèn)為上下文是Java程序和腳本引擎交換數(shù)據(jù)的袋子。JSR 223用接口javax.script.ScriptContext定義上下文這個結(jié)構(gòu)。如果我們向這個袋子里放入很多而又不加以組織的話,這個袋子就會變得非常凌亂。因此腳本上下文(例如ScriptContext的實例)將自己的數(shù)據(jù)劃分到了多個范圍里。JSR 223用接口javax.script.Bindings定義范圍這個結(jié)構(gòu)。圖三展示了上下文、上下文的范圍、以及范圍中存放的數(shù)據(jù)。 圖三 腳本引擎管理器和腳本引擎中的上下文和范圍。圖三里有些信息十分重要:1. 一個腳本引擎包含一個腳本上下文。2. 一個腳本引擎管理器(例如ScriptEngineManager的實例)都可以用來創(chuàng)建多個腳本引擎。3. 腳本引擎管理器包含一個被稱為global scope的全局范圍,但是不包含上下文。4. 每個范圍基本上就是一個名稱-值對的集合。圖三中可以看到有個一個范圍里包含兩個這樣的名稱-值對,一個的名稱是x,另一個的名稱是y。要注意每個范圍都是javas.script.Bindings的一個實例。5. 腳本引擎里的上下文包含了一個全局范圍、一個引擎范圍和0個或多個其他范圍。6. 一個腳本引擎可以用來執(zhí)行多個腳本(例如:腳本語言編寫的多段單獨的腳本片斷)。但是圖三種的全局范圍和引擎范圍是什么呢?全局范圍是一個在多個腳本引擎中共享的范圍。如果你想在多個腳本引擎中共享一部分?jǐn)?shù)據(jù),那就可以將這些數(shù)據(jù)放在全局范圍中。注意全局范圍并不是對所有的腳本引擎來說是全局的。它只對那些被它所在的腳本引擎管理器創(chuàng)建的腳步引起來說是全局的。引擎范圍是一個被多個腳本貢享的范圍。如果你想要在多個腳本中共享數(shù)據(jù),那就可以將這些數(shù)據(jù)放在引擎范圍中。例如,假設(shè)我們有下面兩段腳本:(True & x) | y //Script A(True & x) //Script B如果我們要在這兩個腳本中共享x的值,我們可以把這個值放入執(zhí)行腳本的腳本引擎包含的引擎范圍中。假設(shè)現(xiàn)在我們只想在腳本A中保存y的值,那我們就需要創(chuàng)建一個范圍,記住這個范圍只對腳本A可見,然后將y的值放入這個范圍中。作為例子,BoolScriptHostApp.java的main方法里用下面的代碼計算了(x & y)://bsEngine is an instance of ScriptEnginebsEngine.put('x', BoolTermEvaluator.tTrue);bsEngine.put('y', BoolTermEvaluator.tTrue);bsEngine.eval('x & ynn');這段代碼先將x和y的值放入引擎范圍內(nèi),然后調(diào)用引起的eval()方法執(zhí)行BoolScript代碼。如果你看下ScriptEngine接口,你會發(fā)現(xiàn)eval()方法有很多擁有不同參數(shù)的重載方法。如果像上面那樣使用字符串作為參數(shù)調(diào)用eval()方法,腳本引擎會在他的上下文中執(zhí)行這段代碼。如果不希望在腳本引擎的上下文中執(zhí)行,那就要在調(diào)用eval()時提供上下文。在我們的實現(xiàn)里,eval()的實際工作由BoolTermEvaluator里面的下面這段代碼執(zhí)行:public static BoolTerm evaluate(BoolTerm term, ScriptContext context){ ... else if (term instanceof Var) { Var var = (Var) term; Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE); if (!bindings.containsKey(var.getName())) throw new IllegalArgumentException('Variable ' + var.getName() + ' not set.'); Boolean varValue = (Boolean) bindings.get(var.getName()); if (varValue == Boolean.TRUE) return BoolTermEvaluator.tTrue; else return BoolTermEvaluator.tFalse; } ...}這個方法通過計算Term(True、 False、或變量)來執(zhí)行BoolScript代碼。當(dāng)Term像上面的代碼那樣是一個變量的時候,方法將調(diào)用作為參數(shù)傳入的上下文的getBindings()方法得到引擎范圍的引用。由于一個上下文里可以有多個范圍,所以我們使用ScriptContex.ENGINE_SCOPE表示我們想要得到的是引擎范圍。在得到引擎范圍后,我們使用變量名在引擎范圍中查找變量的值。如果未找到變量的值,則拋出異常。反之,我們將計算這個變量然后返回他的值。最后,我準(zhǔn)備解釋為什么腳本引擎管理器初始化腳本引擎的時候要調(diào)用腳本引擎的setBindings()方法:當(dāng)腳本引擎管理器調(diào)用引擎的setBindings()方法的時候,它將自己的全局范圍作為參數(shù)傳遞給這個方法。引擎則將這個全局范圍存入自己的上下文中。在結(jié)束這個章節(jié)前,讓我們看一下腳本API里的幾個類。前面說過ScriptEngineManager包含了一個Bindings的實例作為全局范圍。如果你看一下javax.script.ScriptEngineManager的源代碼,你可以發(fā)現(xiàn)有一個getBindings()方法用于得到ScriptEngineManager里的Bindings,同樣,還存在一個setBindings()用于設(shè)置ScriptEngineManager的Bindings。和ScriptEngineManager相似,ScriptEngine包含了一個ScriptContext的實例。在接口javax.script.ScriptEngine里也對應(yīng)存在一個getContext()方法和一個setBindings()方法。因此你可以很容易地在腳本引擎管理器之間共享全局范圍。你要做的僅僅是調(diào)用一個腳本引擎管理器的getBindings()方法得到它的全局范圍,然后調(diào)用另一個的setBindings()方法設(shè)置這個全局范圍。如果你看了示例里BoolScriptEngine的代碼,你會發(fā)現(xiàn)里面并沒有ScriptContext的引用。這是因為BoolScriptEngine繼承了AbstractScriptEngine,而AbstractScriptEngine里有一個成員是ScriptContext的實例。如果你自己實現(xiàn)一個腳本引擎,而且沒有繼承父類(如AbstractScriptEngine),那你就需要在你的腳本引擎里保存ScriptContext的實例,并且實現(xiàn)getContext()和setContext()方法。Compilable和Invocable到現(xiàn)在為止,我們已經(jīng)達到了把BoolScript做為JSR 223腳本引擎所需要的最低的要求。每當(dāng)Java程序需要使用我們的腳本引擎的時候,它需要將BoolScript代碼作為字符串傳遞給我們的引擎。引擎內(nèi)部使用一個解析器將這段字符串解析成抽象語法樹(abstract syntax tree),然后將棵樹交給BoolTermEvaluator.evaluate()執(zhí)行。以上的整個過程我們稱為解釋執(zhí)行(interpretation),與之相對的是編譯執(zhí)行(compilation)。在這個過程中,BoolScript引擎被稱為解釋器,與之相對的被稱為編譯器。如果要作為編譯器使用的話,BoolScript引擎要能做到將文本的BoolScript代碼轉(zhuǎn)換成中間形態(tài),這樣在執(zhí)行這段代碼時就不用再解析成抽象語法樹。本章節(jié)講述了如何實現(xiàn)這個功能。Java程序是編譯成稱為Java字節(jié)碼的中間形態(tài)存放在.class文件中。運行時classloader載入.class文件,然后由JVM執(zhí)行字節(jié)碼。BoolScript將使用Java字節(jié)碼作為中間形態(tài),這樣就可以不用自己定義中間形態(tài)和實現(xiàn)自己的虛擬機。JSR 223定義的編譯概念的模型是javax.script.Compilable,因此BoolScriptEngine需要實現(xiàn)這個接口。下面這段BoolScriptHostApp.java里的代碼展示了如何使用可編譯的腳本引擎編譯和執(zhí)行腳本代碼:List boolAnswers = null;//bsEngine is an instance of ScriptEngineCompilable compiler = (Compilable) bsEngine;CompiledScript compiledScript = compiler.compile('x & ynn');Bindings bindings = new SimpleBindings();bindings.put('x', new Boolean(true));bindings.put('y', new Boolean(true));boolAnswers = (List) compiledScript.eval(bindings);printAnswers(boolAnswers);Invocable invocable = (Invocable) bsEngine;boolAnswers = (List) invocable.invoke('eval', new Boolean(true), new Boolean(false));printAnswers(boolAnswers);上面的代碼中,bsEngine是一個ScriptEngine的實例,它實現(xiàn)了Compilable接口。我們將它轉(zhuǎn)換成Compilable,然后調(diào)用compile()方法編譯代碼“x & y。compile()內(nèi)部將“x & y轉(zhuǎn)換成下面的Java代碼:package net.sf.model4lang.boolscript.generated;import java.util.*;import java.lang.reflect.*;class TempBoolClass { public static List eval(boolean x, boolean y) { List resultList = new ArrayList(); boolean result = false; result = x & y; resultList.add(new Boolean(result)); return resultList; }}這個轉(zhuǎn)換將BoolScript代碼轉(zhuǎn)換成Java類中的一個方法。類名和方法名都是硬編碼的。BoolScript里的每個變量都將成為Java方法的一個參數(shù)。將BoolScript代碼轉(zhuǎn)換成Java代碼只完成了一半的工作。之后我們還需要將Java代碼編譯成Java字節(jié)碼。在這我使用Java編譯API(JSR 199,Java SE 6.0的另一個新特性)直接在內(nèi)存中編譯Java代碼。本文不討論Java編譯API,感興趣的讀者可以參考資源部分查找更多的信息。Compilable接口規(guī)定了compile()方法必須返回一個CompiledScript的實例。CompiledScript在JSR 223里是用來定義編譯結(jié)果的模型。不論我們怎么編譯腳本代碼,當(dāng)編譯結(jié)束的時候,我們必須將編譯的結(jié)果封裝成CompiledScript的實例。在示例代碼中,我們定義了一個類BoolCompiledScript繼承CompiledScript,將編譯后的BoolScript代碼存放到這個類中。當(dāng)腳本代碼編譯后,Java程序可以調(diào)用CompiledScript實例的eval()方法反復(fù)地執(zhí)行編譯后的代碼。在我們的例子中,我們調(diào)用CompiledScript的eval()方法的時候,需要將包含x和y變量的腳本上下文傳遞給這個方法,這在上面BoolScriptHostApp.java的代碼中已經(jīng)列出。CompiledScript的eval()并不是唯一可以執(zhí)行編譯后的腳本代碼的方法。如果腳本引擎實現(xiàn)了Invocable接口,我們就可以調(diào)用Invocable接口的invoke()方法執(zhí)行腳本代碼。在我們的簡單示例中,調(diào)用這兩個方法執(zhí)行腳本代碼看上去并沒有什么區(qū)別。但是,實際使用中腳本引擎用戶通常用CompiledScript執(zhí)行整段腳本,而使用Invocable執(zhí)行獨立的函數(shù)(Java里稱為方法)。如果你看一下Invocable的invoke()方法,你可以輕易地發(fā)現(xiàn)CompiledScript和Invocable的區(qū)別。和CompiledScript的eval()方法使用可選的腳本上下文作為參數(shù)不同的是,invoke()方法使用你想執(zhí)行的函數(shù)名作為參數(shù)。在上面引用的BoolScriptHostApp.java的代碼中,腳本引擎實例bsEngine實現(xiàn)了Invocable接口。我們將它轉(zhuǎn)成Invocable并調(diào)用它的invoke()方法。調(diào)用編譯后的腳本的函數(shù)和用反射調(diào)用Java類的方法十分相似。你必須告訴invoke()方法你要調(diào)用的函數(shù)名,同時還要提供這個函數(shù)所需要的參數(shù)。我們已經(jīng)知道我們的函數(shù)名已經(jīng)硬編碼為eval了。因此我們將字符串“eval作為invoke的第一個參數(shù),同時我們還需要將eval的兩個Boolean參數(shù)傳遞給invoke()方法。結(jié)論在這篇文章里,我討論了JSR 223的幾個主要特性:腳本引擎發(fā)現(xiàn)機制、Java綁定、Compilable和Invocable。JSR 223中的Web腳本這里沒有涉及。如果了我們在BoolScript引擎里實現(xiàn)了Web腳本,那我們的腳本引擎使用者就可以在servlet容器里創(chuàng)建Web內(nèi)容了。即使不管和Java的整合,開發(fā)一個語言的編譯器和解釋器也是一個龐大的事業(yè)。根據(jù)語言的復(fù)雜度,編譯器和解釋器的開發(fā)可能會是一個非常麻煩的任務(wù)。感謝JSR 223,將我們的語言和Java整合從來沒有這么簡單過。關(guān)于作者Chaur Wu 是一個軟件開發(fā)人員并出版過書。他曾合著了有關(guān)設(shè)計模式和軟件建模的書籍。他同時也是開源項目Model4Lang管理員,這個項目致力于為語言設(shè)計和構(gòu)造提供基于模型的解決方案。資源+本文中相關(guān)源代碼下載:http://www.javaworld.com/javaworld/jw-04-2006/scripting/jw-0424-scripting.zip+BSF網(wǎng)站:http://jakarta.apache.org/bsf/ +一個JSR 223腳本引擎:http://model4lang.sourceforge.net +JSR 223:http://www.jcp.org/en/jsr/detail?id=223 +Java SE 6.0源碼快照:http://download.java.net/jdk6 +Java SE 6.0 beta下載:http://java.sun.com/javase/6/download.jsp +JSR 199:http://www.jcp.org/en/jsr/detail?id=199 +Matrix:http://www.matrix.org.cn Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd 摘要即將發(fā)布的Java6.0包含了Java平臺腳本(JSR 223)的實現(xiàn)。這個JSR關(guān)注于程序設(shè)計語言以及他們與Java的整合。本文通過一個簡單的“Boolean語言的實現(xiàn)展示了JSR 223的能力和潛力。通過這個例子,你將看到如何?
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 日韩亚洲欧美理论片 | 九九视频在线 | 成人观看免费大片在线观看 | 91精品国产综合久久青草 | 久久亚洲精品中文字幕亚瑟 | 成人18网站 | 日本毛片在线看 | 亚洲不卡一区二区三区在线 | 亚洲精品视频在线看 | 正能量www正能量免费网站 | 国产精品亚洲午夜不卡 | 欧美激情伦妇在线观看 | 91亚洲精品一区二区在线观看 | 拍拍拍又黄又爽无挡视频免费 | 一级成人毛片免费观看 | 未成人做爰视频www 窝窝午夜精品一区二区 | 欧美怡红院在线 | 中文字幕亚洲欧美日韩不卡 | 高清一区二区在线观看 | 黄男人和女人色一级 | 手机在线亚洲 | 亚洲久久成人 | 精品国产高清a毛片无毒不卡 | 国产手机国产手机在线 | 男女免费爽爽爽在线视频 | 在线观看日本亚洲一区 | 国产成人91一区二区三区 | 91亚洲精品国产第一区 | 韩国毛片 免费 | 中文字幕成人在线观看 | 免看一级一片一在线看 | 国产精品区牛牛影院 | 国产成人综合亚洲亚洲欧美 | 美女视频免费看视频网站 | 国产一区曰韩二区欧美三区 | 亚洲韩国欧美一区二区三区 | 加勒比色综合久久久久久久久 | 有码在线 | 成人欧美一区二区三区在线 | 欧美一级片在线看 | 综合精品 |