rhinojava
『壹』 rhino極地模式怎麼出圖
rhino極地模式出圖方法:
打開rhino,在工具-選項-顯示模式中,點擊任意模式(以極地模式為例),點擊復制,得到一個復制的極地模式。同時,點擊「導出」可以將圖片導出。
Rhino是美國Robert McNeel & Assoc開發的PC上強大的專業3D造型軟體,它可以廣泛地應用於三維動畫製作、工業製造、科學研究以及機械設計等領域。
它能輕易整合3DS MAX與Softimage的模型功能部分,對要求精細、彈性與復雜的3D NURBS模型,有點石成金的效能。
能輸出obj、DXF、IGES、STL、3dm等不同格式,並適用於幾乎所有3D軟體,尤其對增加整個3D工作團隊的模型生產力有明顯效果,故使用3D MAX、AutoCAD、MAYA、Softimage、Houdini、Lightwave等3D設計人員不可不學習使用。
Rhino,中文名稱犀牛,是一款超強的三維建模工具。不過不要小瞧它,它包含了所有的NURBS建模功能,用它建模感覺非常流暢,所以大家經常用它來建模,然後導出高精度模型給其他三維軟體使用。
Rhino軟體簡介:
Mozilla Rhino 是一個完全使用java語言編寫的開源JavaScript引擎實現,主要用於在java環境中執行xxx.js 或者 js程序。Rhino通常用於在Java程序中,為最終用戶提供腳本化能力。
Rhino(犀牛)這個名字來源於O'Reilly出版的著名的「犀牛書」JavaScript: The Definitive Guide(中文譯名:JavaScript指南)。
『貳』 openjdk和jdk性能區別 有哪些區別
關於JDK和OpenJDK的區別,可以歸納為以下幾點:
1、授權協議的不同:openjdk採用GPL V2協議放出,而JDK則採用JRL放出。兩者協議雖然都是開放源代碼的,但是在使用上的不同在於GPL V2允許在商業上使用,而JRL只允許個人研究使用。OpenJDK不包含Deployment(部署)功能部署的功能包括:Browser Plugin、Java Web Start、以及Java控制面板,這些功能在Openjdk中是找不到的。
2、OpenJDK源代碼不完整。這個很容易想到,在採用GPL協議的Openjdk中,sun jdk的一部分源代碼因為產權的問題無法開放openjdk使用,其中最主要的部份就是JMX中的可選元件SNMP部份山擾的代碼。而Icedtea則為這些不完整的部分開發了相同功能的源代碼(OpenJDK6),促使OpenJDK更加完整。
3、部分源代碼用開源代碼替換。由於產權的問題,很多產權不是SUN的源代碼被替換成一些功能相同的開源代碼,比如說字體柵格化引擎,使用Free Type代替。
4、openjdk只包含最精簡的JDK。OpenJDK不包含其他的軟體包,比如Rhino Java DB JAXP……,並且可以分離的軟體包也都是盡量的分離,但是這大多數都是自由軟體,你可以自己下載加入。
5、不能使用祥賀Java商標。這個很容易理解,在安裝openjdk的機器上,輸入謹唯派「java -version」顯示的是openjdk,但是如果是使用Icedtea補丁的openjdk,顯示的是java。(未驗證)。
『叄』 運用java與javascript集合對象運用能力以及對字元串解析
Java用ScriptEngine解析腳本
javax.script,始於JDK1.6,不過現在只有sun實現的JavaScript的解析器,難道是因為主要用來解析js語法所以歸類到JEE的范疇?不過基本足夠了,一般的用途主要是能解析通用的表達式就好,比如X >= 1(X作為參數傳入)這樣的表達式,也能利用js的函數語法,創造一個就像Java的函數一樣存在於內存中隨時可以被調用的函數,更可以將js中的對象直接轉換成java對象。
Script主要類及介面
ScriptEngineManager、ScriptEngine、CompiledScript和Bindings 4個類或介面
ScriptEngineManager是一個工廠的集合,可以通過name或tag的方式獲取某個腳本的工廠並生成一個此腳本的ScriptEngine,目前只有javascript的工廠。通過工廠函數得到了ScriptEngine之後,就可以用這個對象來解析腳本字元串了,直接調用Object obj = ScriptEngine.eval(String script)即可,返回的obj為表達式的值,比如true、false或int值。
CompiledScript可以將ScriptEngine解析一段腳本的結果存起來,方便多次調用。只要將ScriptEngine用Compilable介面強制轉換後,調用compile(String script)就返回了一個CompiledScript對象,要用的時候每次調用一下CompiledScript.eval()即可,一般適合用於js函數的使用。
Bindings的概念算稍微復雜點,我的理解Bindings是用來存放數據的容器。它有3個層級,為Global級、Engine級和Local級,前2者通過ScriptEngine.getBindings()獲得,是唯一的對象,而Local Binding由ScriptEngine.createBindings()獲得,很好理李好信解,每次都產生一個新的。Global對應到工廠,Engine對應到ScriptEngine,向這2者裡面加入任何數據或者編譯後的腳本執行對象,在每一份新生成的Local Binding裡面都會存在。
ScriptEngine代碼示例
先來看一段襪碧JS
var arrclass = new Array();
arrclass.push(new Class(20000,"計算機-軟體開發"));
arrclass.push(new Class(30000,"計算機-網路/通訊"));
arrclass.push(new Class(10000,"計算機-硬體開發"));
arrclass.push(new Class(40000,"計算機-管理"));
arrclass.push(new Class(50000,"計算機-品質管理/技術支持"));
arrclass.push(new Class(320000,"電子/電器/半導體/儀器儀表"));
java代碼實現解析
public void parseJS() {
//1、通過哪輪Http請求獲取js的String數據,格式如上
String jsData = getJsData("url");
//2、觀察js結構,自定義Class,push到數組中,java中需要定義跟js中的Class的聲明
String clazz = "function Class(classId, className){ this.classId=classId;this.className=className};";
//3、初始化ScriptEngine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
//4、js中未定義返回對象,這里需要將Class數據轉換成字元串的數組返回,個人覺得很別扭,不知道是理解錯誤還是確實如此?
//如果不這樣做則直接在js後加上arrclass,cScript.evel()則返回NativeObject對象的數組
String fun = "var result = new Array() ;for(var i=0;i <arrclass.length;i++){result.push(new Array(arrclass[i].classId,arrclass[i].className))}; result;";
Compilable compilable = (Compilable) engine;
//4、使用NativeArray獲取數據
CompiledScript cScript;
try {
cScript = compilable.compile(clazz + jsData + fun);
NativeArray na = (NativeArray) cScript.eval();
for (int i = 0; i < na.getLength(); i++) {
NativeArray nv = (NativeArray) na.get(i, null);
System.out.println(nv.get(0, null).toString() + " " + nv.get(1, null).toString());
}
} catch (ScriptException ex) {
ex.printStackTrace();
}
}
java代碼中執行js計算
public void js() {
// 創建腳本引擎管理器
ScriptEngineManager sem = new ScriptEngineManager();
// 創建一個處理JavaScript的腳本引擎
ScriptEngine engine = sem.getEngineByExtension("js");
try {
// 執行js公式
engine.eval("if(6>5){flag=true;}else{flag =false;}");
} catch (ScriptException ex) {
ex.printStackTrace();
}
//看看我們預期的反饋結果 true
System.out.println(engine.get("flag"));
}
Java解析JS另一大引擎-Rhino
Rhino是完全用Java編寫的JavaScript的開放源代碼實現。它通常是嵌入到Java應用程序提供給最終用戶的腳本。它被鑲嵌在J2SE6作為默認的Java腳本引擎。
使用Rhino來解析,感覺一切都很清晰明朗.
public void parseJS() {
//1、通過Http請求獲取js的String數據,格式如上
String jsData = getJsData("url");
//2、定義跟js中的Class的聲明
String clazz = "function Class(classId, className){ this.classId=classId;this.className=className};";
//3、初始化Context
Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects();
Object result = cx.evaluateString(scope, clazz + jsData + ";arrclass", "arrclass", 1, null);
System.out.println(NativeJSON.stringify(cx, scope, result, null, null));
Context.exit();
}
『肆』 Rhino 和 Nashorn 到底怎麼運行
嗯這個問題得剝開幾層說。其實很容易理解。這里我們先忽略JVM是用什麼語言實現的。要詳細考察這個問題可以去看另一個回答:Java 平台中的 JVM 和 .Net 平台下的 CLR 分別是用什麼語言寫的? - RednaxelaFX 的回答 ( 語法分析器 Parser ) -> [ 抽象語法樹(AST) ast ] -> ( Rhino內部表現形式生成器 IRFactory ) -> [ Rhino內部表現形式 ScriptNode ] -> ( Rhino位元組碼生成器 CodeGenerator ) -> [ Rhino位元組碼 Icode ] -> ( Rhino解釋器 Interpreter ) -> [ 運行結果 ]這里說的Rhino位元組碼是Rhino內部用來表示JavaScript程序語義的一套位元組碼,跟JVM所支持的Java位元組碼沒關系。當優化級別為0~9時,Rhino使用一個用Java寫的編譯器將JavaScript編譯為Java位元組碼;生成出來的Java位元組碼交由JVM直接執行。至於底下的JVM是解釋執行Java位元組碼,還是將Java位元組碼編譯為機器碼再執行,Rhino並不關心。此時,Rhino的工作流程簡單說是:[ JavaScript源碼 ] -> ( 語法分析器 Parser ) -> [ 抽象語法樹(AST) ast ] -> ( Rhino內部表現形式生成器 IRFactory ) -> [ Rhino內部表現形式 ScriptNode ] -> ( 可選優化 Optimizer ) -> ( Java位元組碼生成器 Codegen ) -> [ Java Class文件(包含Java位元組碼) ] -> JVM載入和執行生成的位元組碼 -> [ 運行結果 ]這種以編譯的方式模式執行JavaScript,跟一個Java源碼編譯器(例如javac)把Java源碼編譯為Class文件然後交由JVM執行,過程是類似的。只不過Rhino做的優化不夠多而且JavaScript的語義也遠比Java動態,所以此時Rhino上運行JavaScript的性能仍然無法跟Java的性能比。順帶一提,Sun/Oracle JDK6 / OpenJDK6中自帶的Rhino是經過裁剪的,去掉了Mozilla Rhino中的部分功能。其中一個被去掉的功能就是Rhino的編譯模式。這意味著JDK6自帶的Rhino只能用解釋模式運行。而Oracle JDK7 / OpenJDK7放寬了這一限制,當有SecurityManager時只能用解釋模式,否則可以配置"rhino.opt.level"系統屬性來設置Rhino的優化級別;默認仍然是用解釋模式(優化級別默認為-1)。pile()開始看:[ JavaScript源碼 ] -> ( 語法分析器 Parser ) -> [ 抽象語法樹(AST) ir ] -> ( 編譯優化 Compiler ) -> [ 優化後的AST + Java Class文件(包含Java位元組碼) ] -> JVM載入和執行生成的位元組碼 -> [ 運行結果 ]中間這個「編譯優化」通過CompilationPhase來組織。最基本的工作流程可以從Compiler.CompilationPhases.COMPILE_ALL來看。它包含一系列CompilationPhase:CONSTANT_FOLDING_PHASELOWERING_PHASETRANSFORM_BUILTINS_PHASESPLITTING_PHASEPROGRAM_POINT_PHASESERIALIZE_SPLIT_PHASESYMBOL_ASSIGNMENT_PHASESCOPE_DEPTH_COMPUTATION_PHASEOPTIMISTIC_TYPE_ASSIGNMENT_PHASELOCAL_VARIABLE_TYPE_CALCULATION_PHASEBYTECODE_GENERATION_PHASEINSTALL_PHASE我在ADC2013做過一次關於Nashorn的演講:博客收集帖Rhino 和 Nashorn 到底怎麼運行
『伍』 為什麼瀏覽器可以保存網頁中js動態內容,用java編寫的爬蟲卻無法抓取
爬蟲最多隻能抓取頁面載入完畢時的內容,怎麼可能慢慢等你網頁後續動態顯示出來的內容呢
『陸』 java未來發展趨勢
雖然只有10歲,卻猶如35歲的青壯年一般,Java已經迅速地在眾多領域確立了其地位:對等網路、開放源代碼、無線開發和嵌入式應用程序等等,這還只是其中一些。要准確地把握這門語言的走向是很困難的,因為它正在同時向各個方向齊頭並進。
關於快速開發的一切
毫無疑問:腳本編寫語言,例如Jython、Python、Perl和PHP,正在被越來越多地使用。Jython事實上就是Python編程語言的完整實現。它100%使用純Java編寫而成,並允許對Java庫的輕松訪問。
這種腳本編寫的趨勢在很大程度上是由快速應用程序開發(RAD)推動的,這是一種始終都能夠贏得追隨者的開發風格。由於市場營銷的執行者逼迫IT的生產公司加速產品的開發,因此IT的管理者被迫尋找最有效的方式來滿足最終期限的要求。在這里RAD是主要的源動力。
「你可能很擅長某些腳本語言,並且能夠完成常規Java所不能完成的任務,」Mukund Balasubramanian說。他是位於加利福尼亞州雷德伍德城的Infravio的首席技術官,負責著Java和Web服務的集成。「如果你知道如何使用一門優秀的語言,你就可以在開發中省下很多的時間和金錢。」
腳本語言的優勢
Balasubramanian說,腳本語言具有下列優勢:
快速開發:腳本語言極大地簡化了「開發、部署、測試和調試」的周期過程。
容易部署:大多數腳本語言都能夠隨時部署,而不需要耗時的編譯/打包過程。
同已有技術的集成:腳本語言被Java或者COM這樣的組件技術所包圍,因此能夠有效地利用代碼。
易學易用:很多腳本語言的技術要求通常要低一些,因此能夠更容易地找到大量合適的技術人員。
動態代碼:腳本語言的代碼能夠被實時生成和執行,這是一項高級特性,在某些應用程序里(例如JavaScript里的動態類型)是很有用也是必需的。
腳本語言的劣勢
但是,Java腳本語言有下面這些劣勢:
腳本語言不夠全面。它們會要求一門「真正的」編程語言的存在;例如,你必須找一個資料庫驅動程序將其內置進腳本語言里。
腳本語言並不是軟體工程和構建代碼結構的最佳選擇,例如面向對象和基於組件的開發。
腳本語言通常不是「通用」語言,但是能夠根據專門的應用來調整,例如PHP和萬維網。
「因此,腳本語言能夠在很大程度上加速軟體的開發,但是必須要根據具體的應用來仔細選擇——例如動態Web頁面,或者對『真正的』編程語言進行補充,就像Jython是對Java的補充一樣,」Balasubramanian說。
像IBM的Bean腳本編寫框架(Bean Scripting Framework)這樣的工具使得將Tcl、Python、Perl和其他腳本語言融合進Java應用程序變得相當容易。Sun、Borland、BEA和其他的公司也提供了類似的工具。但是俄勒岡州威爾遜維爾的Mentor Graphics的資深Java開發人員David Kearns指出,支持一門腳本語言就存在耗時和耗錢的風險,不要說支持六門語言了。
在其最近為Java世界所撰寫的一篇文章中,Kearns描述了在你Java應用程序里支持腳本語言所固有的風險。
「在我看來,Jython具有最快的腳本解釋器,並有一些強大的編程特性,」他說。「我唯一真正關心的是Jython的控制流句法(control-flow syntax),這可能對你來說很重要,也可能不重要。對於Jacl而言,編寫用於Jython的腳本的學習曲線可能要比JavaScript或者BeanShell高,(即學習前者要比學習後兩者困難),因為有更多的新東西要學習。如果你想要在Python里編寫不同尋常的腳本,那麼我推薦你去買本書看看。Python是一門很常見的編程語言,所以你在書店裡會有很多的選擇。
其他Java腳本語言
下面列舉出了一些使用最廣泛的面向Java的腳本語言,感謝Java老手——About.com的William Wagers提供這些內容:
Beanshell
BeanShell是一個簡短的、免費的、可下載的、可嵌入的Java源代碼解釋器,它具有使用Java編寫成的對象腳本語言的特性。除了普通的腳本命令和句法之外,BeanShell還能夠執行標準的Java陳述式和表達式。它能夠將腳本對象作為簡單的方法閉塞(method closure)來支持,就像Perl和JavaScript里的一樣。
Jess
Jess是一個完全使用Java語言編寫的規則引擎(rule engine)和腳本環境。Jess最初的靈感來自CLIPS專家系統,但是現在它已經發展成為一個完整的、卓越的動態環境。使用Jess,你能夠創建Java applet以及應用程序,並讓這些程序根據以說明規則(declarative rule)的形式所提供的信息進行「推理」。
JudoScript
JudoScript是一個Java類的腳本,它具有很多特性:HTTP客戶端和伺服器編程、文件系統和歸檔、XML和XSLT腳本編寫、JDBC腳本編寫,以及HTML修飾能力(scraping)。它還有值得炫耀的帶有監控程序的調度程序、sendmail、運行可執行(run executable)、Java GUI的創建、FTP、SSH和SCP,以及Windows注冊表等等。這個軟體可下載,包括源代碼,都是免費的。
Rhino
Rhino使用純Java編寫而成,是一個開放源代碼的JavaScript的實現。它通常被嵌入到Java應用程序里,用來向終端用戶提供腳本編寫的能力。
『柒』 rhino什麼時候學
rhino一款軟體的學習時間是2~3個月
前提是能夠系統的接受學習的情況下,如果選擇自學的陸蔽話除非有強大的自控力,能夠自我監督完成各旁行項學習與練習,那麼自學的方式也是可以接受運悉嘩的。
『捌』 rhino是不是比不過google V8
v8是直接編譯,主要是通過c++編寫的解釋器執行
rhino是基於java runtime之上開發的
語言這玩意,誰離內核最近,誰的效率就越高,所以rhino是比不上v8
但是LZ,mozilla做的Gecko又比谷歌的webkit效率高(具體樓主可以同機不同瀏覽器看渲染實測,明顯的同一個程序webkit會掉幀,在mac上的safari不做參考,那是高度定製的渲染內核了)
『玖』 java,javascript,groovy和Rhino 的運行效率到底相差的有多遠
您好,很高興為您解答。
看下這個測試:http://blog.csdn.net/emu/article/details/424301
如若滿意,請點擊右側【御判遲採納答案】,如若還有問題,請鎮李點擊【沖敏追問】
希望我的回答對您有所幫助,望採納!
~ O(∩_∩)O~
『拾』 java nashorm怎麼用
從JDK 6開始,Java就已經捆綁了JavaScript引擎,該引擎基於Mozilla的Rhino。該特性允許開發人員將JavaScript代碼嵌入到Java中,甚至從嵌入的JavaScript中調用Java。此外,它還提供了使用jrunscript從命令行運行JavaScript的能力。如果不需要非常好的性能,並且可以接受ECMAScript 3有限的功能集的話,那它相當不錯了。
從JDK 8開始,Nashorn取代Rhino成為Java的嵌入式JavaScript引擎。Nashorn完全支持ECMAScript 5.1規范以及一些擴展。它使用基於JSR 292的新語言特性,其中包含在JDK 7中引入的invokedynamic,將JavaScript編譯成Java位元組碼。
與先前的Rhino實現相比,這帶來了2到10倍的性能提升,雖然它仍然比Chrome和Node.js中的V8引擎要差一些。如果你對實現細節感興趣,那麼可以看看這些來自2013 JVM語言峰會的幻燈片。
相關廠商內容
滴滴出行iOS客戶端架構演進之路!
微信客戶端如何應對弱網路!
函數式編程中的Swift與Swift中的函數式編程!
AWS Webinar 5月24日在線課堂|利用AWS Lambda創建應用
國際范 最前沿 不容錯過的容器技術盛會
相關贊助商
GMTC全球移動技術大會2016年6月24日-25日,北京,點擊了解詳情!
由於Nashorn隨JDK 8而來,它還增加了簡潔的函數式介面支持。接下來,我們很快就會看到更多細節。
讓我們從一個小例子開始。首先,你可能需要安裝JDK 8和NetBeans、IntelliJ IDEA或者Eclipse。對於集成JavaScript開發,它們都至少提供了基本的支持。讓我們創建一個簡單的Java項目,其中包含下面兩個示例文件,並運行它:
(點擊圖片可以查看大圖)
在第12行,我們使用引擎的「eval」方法對任意JavaScript代碼求值。在本示例中,我們只是載入了上面的JavaScript文件並對其求值。你可能會發現那個「print」並不熟悉。它不是JavaScript的內建函數,而是Nashorn提供的,它還提供了其它方便的、在腳本環境中大有用武之地的函數。你也可以將 「hello world」的列印代碼直接嵌入到傳遞給「eval」方法的字元串,但將JavaScript放在它自己的文件中為其開啟了全新的工具世界。
Eclipse目前還沒有對Nashorn提供專門的支持,不過,通過JavaScript開發工具(JSDT)項目,它已經支持JavaScript的基本工具和編輯。
(點擊圖片可以查看大圖)
IntelliJ IDEA 13.1(社區版和旗艦版)提供了出色的JavaScript和Nashorn支持。它有一個全功能的調試器,甚至允許在Java和JavaScript之間保持重構同步,因此舉例來說,如果你重命名一個被JavaScript引用的Java類,或者重命名一個用於Java源代碼中的JavaScript文件,那麼該IDE將跨語言修改相應的引用。
下面是一個例子,展示如何調試從Java調用的JavaScript(請注意,NetBeans也提供了JavaScript調試器,如下截圖所示):
(點擊圖片可以查看大圖)
你可能會說,工具看上去不錯,而且新實現修復了性能以及一致性問題,但我為什麼應該用它呢?一個原因是一般的腳本編寫。有時候,能夠直接插入任何類型的字元串,並任由它被解釋,會很方便。有時候,沒有礙事的編譯器,或者不用為靜態類型擔心,可能也是不錯的。或者,你可能對Node.js編程模型感興趣,它也可以和Java一起使用,在本文的末尾我們會看到。另外,還有個情況不得不提一下,與Java相比,使用JavaScript進行JavaFX開發會快很多。
Shell腳本
Nashorn引擎可以使用jjs命令從命令行調用。你可以不帶任何參數調用它,這會將你帶入一個交互模式,或者你可以傳遞一個希望執行的JavaScript文件名,或者你可以用它作為shell腳本的替代,像這樣:
#!/usr/bin/env jjs
var name = $ARG[0];
print(name ? "Hello, ${name}!" : "Hello, world!");
向jjs傳遞程序參數,需要加「—」前綴。因此舉例來說,你可以這樣調用:
./hello-script.js – Joe
如果沒有「—」前綴,參數會被解釋為文件名。
向Java傳遞數據或者從Java傳出數據
正如上文所說的那樣,你可以從Java代碼直接調用JavaScript;只需獲取一個引擎對象並調用它的「eval」方法。你可以將數據作為字元串顯式傳遞……
ScriptEngineManager scriptEngineManager =
new ScriptEngineManager();
ScriptEngine nashorn =
scriptEngineManager.getEngineByName("nashorn");
String name = "Olli";
nashorn.eval("print('" + name + "')");
……或者你可以在Java中傳遞綁定,它們是可以從JavaScript引擎內部訪問的全局變數:
int valueIn = 10;
SimpleBindings simpleBindings = new SimpleBindings();
simpleBindings.put("globalValue", valueIn);
nashorn.eval("print (globalValue)", simpleBindings);
JavaScript eval的求值結果將會從引擎的「eval」方法返回:
Integer result = (Integer) nashorn.eval("1 + 2");
assert(result == 3);
在Nashorn中使用Java類
前面已經提到,Nashorn最強大的功能之一源於在JavaScript中調用Java類。你不僅能夠訪問類並創建實例,你還可以繼承他們,調用他們的靜態方法,幾乎可以做任何你能在Java中做的事。
作為一個例子,讓我們看下來龍去脈。JavaScript沒有任何語言特性是面向並發的,所有常見的運行時環境都是單線程的,或者至少沒有任何共享狀態。有趣的是,在Nashorn環境中,JavaScript確實可以並發運行,並且有共享狀態,就像在Java中一樣:
// 訪問Java類Thread
var Thread = Java.type("java.lang.Thread");
// 帶有run方法的子類
var MyThread = Java.extend(Thread, {
run: function() {
print("Run in separate thread");
}
});
var th = new MyThread();
th.start();
th.join();
請注意,從Nashorn訪問類的規范做法是使用Java.type,並且可以使用Java.extend擴展一個類。
令人高興的函數式
從各方面來說,隨著JDK 8的發布,Java——至少在某種程度上——已經變成一種函數式語言。開發人員可以在集合上使用高階函數,比如,遍歷所有的元素。高階函數是把另一個函數當作參數的函數,它可以用這個函數參數做些有意義的事情。請看下面Java中高階函數的示例:
List<Integer> list = Arrays.asList(3, 4, 1, 2);
list.forEach(new Consumer() {
@Override
public void accept(Object o) {
System.out.println(o);
}
});
對於這個例子,我們的傳統實現方式是使用一個「外部」循環遍歷元素,但現在,我們沒有那樣做,而是將一個「Consumer」函數傳遞給了「forEach」操作,一個高階的「內部循環」操作會將集合中的每個元素一個一個地傳遞給Consumer的「accept」方法並執行它。
如上所述,對於這樣的高階函數,函數式語言的做法是接收一個函數參數,而不是一個對象。雖然在傳統上講,傳遞函數引用本身超出了Java的范圍,但現在,JDK 8有一些語法糖,使它可以使用Lambda表達式(又稱為「閉包」)來實現那種表示方式。例如:
List<Integer> list = Arrays.asList(3, 4, 1, 2);
list.forEach(el -> System.out.println(el));
在這種情況下,「forEach」的參數是這樣一個函數引用的形式。這是可行的,因為Customer是一個函數式介面(有時稱為「單一抽象方法(Single Abstract Method)」類型或「SAM」)。
那麼,我們為什麼要在討論Nashorn時談論Lambda表達式呢?因為在JavaScript中,開發人員也可以這樣編寫代碼,而在這種情況下,Nashorn可以特別好地縮小Java和JavaScript之間的差距。尤其是,它甚至允許開發人員將純JavaScript函數作為函數式介面(SAM類型)的實現來傳遞。
讓我們來看一些純JavaScript代碼,它們與上述Java代碼實現一樣的功能。注意,在JavaScript中沒有內置的列表類型,只有數組;不過這些數組的大小是動態分配的,而且有與Java列表類似的方法。因此,在這個例子中,我們調用一個JavaScript數組的「for Each」方法:
var jsArray = [4,1,3,2];
jsArray.forEach(function(el) { print(el) } );