現在的位置: 首頁 > 編程語言 > 正文

哪些腳本語言支持API

2020年06月08日 編程語言 ⁄ 共 7224字 ⁄ 字號 評論關閉

  JAVA語言是一種靜態類型的編程語言。靜態類型的含義是指在編譯的時候進行類型檢查。JAVA源代碼中的每個每個變量的類型都需要顯式地進行聲明。所有的變量、方法的參數和返回值的類型在程序運行之前就必須是已知的。下面學步園小編來講解下哪些腳本語言支持API?

  哪些腳本語言支持API

  隨著JAVA平臺的流行,很多的腳本語言(scriptinglanguage)都可以運行在JAVA虛擬機上,其中比較流行的有JavaScript、JRuby、Jython和Groovy等。對于這些運行在JAVA虛擬機平臺上的腳本語言來說,并不需要為它們準備額外的運行環境,直接復用已有的JAVA虛擬機環境即可。在應用開發中使用腳本語言,實際上是"多語言開發"的一種很好的實踐,即根據應用的需求和語言本身的特性來選擇最合適的變成語言,以快速高效的解決應用中的問題,比如一個一用,可以用Groovy來編寫用戶界面,用Java編寫核心業務邏輯,用Ruby來進行數據處理,不同的語言編寫的代碼可以同時運行在同一個JAVA虛擬機上。這些腳本語言于Java語言之間的交互,是由腳本語言支持API來完成的。

  1、腳本引擎

  來一個簡單的例子(相當于java中System.out.println方法),了解一下腳本引擎的用法,代碼如下

  publicvoidgreet()throwsScriptException{

  ScriptEngineManagermanager=newScriptEngineManager();

  ScriptEngineengine=manager.getEngineByName("JavaScript");

  if(engine==null)

  thrownewRuntimeException("未找到JavaScript語言執行引擎");

  engine.eval("println('HelloWorld!');");

  }

  上面的代碼中我們是通過腳本引擎的名稱來查找的。實際上,腳本引擎管理器提供了三種查找腳本引擎的方式,分別是通過名稱、文件擴展名和MIME類型來完成,如:

  ScriptEngineengine=manager.getEngineByExtension("js");

  ScriptEngineengine=manager.getEngineByMimeType("text/javascript");

  ScriptEngineengine=manager.getEngineByName("JavaScript");

  2、語言綁定所謂的語言綁定對象就是一個簡單的哈希表,用來存放和獲取需要共享的數據。所有的數據都對應這個哈希表中的一個條目,是簡單的鍵值對。接口javax.script.Bindings定義了語言綁定對象的接口,它繼承自java.util.Map接口。一個腳本引擎在執行過程中可能會使用多個語言綁定對象,用來存放在執行過成功產生的全局對象等。ScriptEngine類提供了put和get方法對腳本引擎中特定作用域的默認語言綁定對象進行操作。程序可以直接使用這個默認的語言綁定對象,也可以使用自己的語言綁定對象。在腳本語言的執行過程中,可以將語言綁定對象看成是一個額外的變量映射表。

  腳本引擎默認的語言綁定對象示例:

  首先通過ScriptEngine的put方法向腳本引擎默認的語言綁定對象中添加一個名為name的字符串,接著在腳本中直接根據名稱來引用這個對象。同樣,在腳本中創建的全局變量message也可以通過ScriptEngine的get方法來獲取。這樣就實現了Java程序與腳本之間的雙向數據傳遞。數據傳遞過程中的類型轉換是有腳本引擎類完成的,轉換規則取決于具體的腳本語言的語法。

  publicvoiduseDefaultBinding()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  engine.put("name","andy");

  engine.eval("varmessage='Hello,'+name;");

  engine.eval("println(message);");

  Objectobj=engine.get("message");

  System.out.println(obj);

  }

  自定義語言綁定對象的示例:

  如果希望使用自己的語言綁定對象,可以調用腳本引擎的createBindings方法或者創建一個javax.script.SimpleBindings對象,并傳遞給腳本引擎的eval方法。通過eval方法傳遞的語言綁定對象,僅在當前eval調用中生效,并不會改變引擎默認的語言綁定對象

  publicvoiduseCustomBinding()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  Bindingsbindings=newSimpleBindings();

  bindings.put("hobby","playinggemes");

  engine.eval("println('Ilike'+hobby);",bindings);

  }

  3、腳本執行上下文

  與腳本引擎相關的另外一個重要的接口是javax.script.ScriptContext,其中包含腳本引擎執行過程中的相關上下文信息,可以與JavaEE中的servlet規范中的javax.servlet.ServletContext接口進行類型。腳本引擎通過此上下文對象來獲取與腳本執行相關的信息,也允許開發人員通過次對象類配置腳本引擎的行為。該上下文對象中主要包括3類信息。

  3.1、輸入輸出

  其中包括腳本在執行中用來讀取數據輸入的java.io.Reader對象以及輸出正確內容和錯誤信息的java.io.Writer對象。在默認情況下,腳本的輸入輸出都發生在標準控制臺中,如果希望把腳本的輸出寫入到文件中,可以通過setWriter方法把腳本的輸出重定向到一個文件中。通過ScriptContext的setReader和setErrorWriter方法可以分別設置腳本執行時的數據出入來源和產生錯誤時的出錯信息的輸出目的。代碼如下:

  publicvoidscriptToFile()throwsIOException,ScriptException{

  ScriptEngineengine=getScriptEngine();

  ScriptContextcontext=engine.getContext();

  context.setWriter(newFileWriter("output.txt"));

  engine.eval("println('HelloWorld!');");

  }

  哪些腳本語言支持API

  3.2、自定義屬性

  ScriptContext中也有與ServletContext中類似的獲取和設置屬性的方法,即setAttribute和getAttribute.所不同的是ScriptContext中的屬性是有作用于之分的。設置屬性的時候需要顯式地指定所在的作用于。在獲取屬性的時候,即可以選擇指定的作用于中查找,也可以選擇根據作用于優先級自動進行查找。腳本上下文實現中包含的作用域是固定的,開發人員不能隨意定義自己的作用于。通過ScriptContext的getScopes方法可以得到所有可用的作用于列表。ScriptContext中預先定義了兩個作用于:常量ScriptContext.GLOBAL_SCOPE表示的作用于對應的是從一個引擎工廠中創建出來的所有腳本引擎對象,而ScriptContext.ENGINE_SCOPE表示的作用域對應的是當前的腳本引擎。后者優先于前者。

  [nextpage[

  作用域影響同名屬性查找的示例:

  ENGINE_SCOPE中的屬性name隱藏了GLOBAL_SCOPE中的同名屬性

  publicvoidscriptContextAttribute()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  ScriptContextcontext=engine.getContext();

  context.setAttribute("name","shanshouchen",ScriptContext.ENGINE_SCOPE);

  context.setAttribute("name","andy",ScriptContext.GLOBAL_SCOPE);

  engine.eval("println(name);");//值為shanshouchen

  }

  3.3、語言綁定對象

  腳本執行上下文中的最后一類信息是語言綁定對象。語言綁定對象也是與作用于相對應的。同樣的作用域優先順序對語言綁定對象也適用。這樣的優先級順序會對腳本執行時的變量解析產生影響。

  語言綁定對象的優先級順序的示例:

  兩個不同的語言綁定對象中都有名稱為name的對象,而在腳本的執行過程中,作用域ENGINE_SCOPE的語言綁定對象的優先級較高,因此變量name的值是"andy"

  publicvoidscriptContextBindings()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  ScriptContextcontext=engine.getContext();

  Bindingsb1=engine.createBindings();

  b1.put("name","shanshouchen");

  context.setBindings(b1,ScriptContext.GLOBAL_SCOPE);

  Bindingsb2=engine.createBindings();

  b2.put("name","andy");

  context.setBindings(b2,ScriptContext.ENGINE_SCOPE);

  engine.eval("println(name);");

  }

  通過ScriptContext的setBindings方法設置的語言綁定對象會影響到ScriptEngine在執行腳本時的變量解析。ScriptEngine的put和get方法所操作的實際上就是ScriptContext的作用域為ENGINE_SCOPE的語言綁定對象。如下代碼,從ScriptContext中得到語言綁定對象之后,可以直接對這個對象進行操作。如果在ScriptEngine中的eval方法中沒有指明的語言綁定對象,實際上起作用的是ScriptContext中作用域為ENGINE_SCOPE的語言綁定對象

  通過腳本執行上下文獲取語言綁定對象的示例:

  publicvoiduseScriptContextValues()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  engine.put("name","shanshouchen");

  ScriptContextcontext=engine.getContext();

  Bindingsbindings=context.getBindings(ScriptContext.GLOBAL_SCOPE);

  bindings.put("name","andy");

  engine.eval("println(name);");//輸出andy

  }

  不直接操作語言綁定對象本身,通過ScriptContext的setAttribute類像語言綁定對象中添加數據。所添加的數據在腳本執行時也同樣是可見的

  自定義屬性保存在語言綁定對象中的示例:

  publicvoidattributeInBindings()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  ScriptContextcontext=engine.getContext();

  context.setAttribute("name","Andy",ScriptContext.GLOBAL_SCOPE);

  engine.eval("println(name);");//輸出為Andy

  }

  4、方法調用

  在腳本中,最常見和最實用的就是方法。有些腳本引擎允許使用者單獨調用腳本中的某個方法。支持這種方法調用方式的腳本引擎可以實現javax.script.Invocable接口。通過Invocable接口可以調用腳本中的頂層方法,也可以調用對象中的成員方法。如果腳本中頂層方法或者對象中的成員方法實現了JAVA中的接口,可以通過Invocable接口中的方法來調用腳本中相應的JAVA接口的實現對象。這樣可以在JAVA語言中定義接口,在腳本中實現接口。程序中使用該接口的其他部分代碼并不知道接口是由腳本來實現的。與Compilable接口一樣,ScriptEngine對Invocable接口的實現也是可選的。

  在JAVA中調用腳本中頂層方法的示例:

  通過Invocable接口的invokeFunction來調用腳本中的頂層方法,調用時的參數會被傳遞給腳本中的方法。因為JAVASE自帶的JavaScript腳本引擎實現了Invocable接口,所以這里省去了對引擎是否實現了Invocable接口的判斷

  publicvoidinvokeFunction()throwsScriptException,NoSuchMethodException{

  ScriptEngineengine=getScriptEngine();

  StringscriptText="functiongreet(name){println('Hello,'+name);}";

  engine.eval(scriptText);

  Invocableinvocable=(Invocable)engine;

  invocable.invokeFunction("greet","Alex");

  }

  在JAVA中調用腳本中對象的成員方法的示例:

  如果被調用的方法是腳本中對象成員方法,就需要使用invokeMethod方法,代碼中的getGreeting方法是屬性對象obj的,在調用的時候把這個對象作為參數傳遞進來。

  publicvoidinvokeMethod()throwsScriptException,NoSuchMethodException{

  ScriptEngineengine=getScriptEngine();

  StringscriptText="varobj={getGreeting:function(name){return'Hello,'+name;}};";

  engine.eval(scriptText);

  Invocableinvocable=(Invocable)engine;

  Objectscrpe=engine.get("obj");

  Objectresult=invocable.invokeMethod(scrpe,"getGreeting","Alex");

  System.out.println(result);

  }

  在腳本中實現JAVA接口的示例:

  在有些腳本引擎中,可以在JAVA語言中定i接口,并在腳本中編寫接口的實現。這樣程序中的其他部分可以只同JAVA接口交互,并不需要關心接口是由什么方式來實現的。代碼清單中,Greet是用JAVA定義的接口,其中包含一個getGreeting方法。在腳本中實現這個接口。通過getInterface方法可以得到由腳本實現的這個接口的對象,并調用其中的方法。

  publicvoiduseInterface()throwsScriptException{

  ScriptEngineengine=getScriptEngine();

  StringscriptText="functiongetGreeting(name){return'Hello,'+name;}";

  engine.eval(scriptText);

  Invocableinvocable=(Invocable)engine;

  Greetgreet=invocable.getInterface(Greet.class);

  System.out.println(greet.getGreeting("Alex"));

  }

  Greet.java

  publicinterfaceGreet{

  StringgetGreeting(Stringname);

  }

  注:方法invokeMethod與方法invokeFunction的用法差不多,區別在于invokeMethod要指定包含帶調用方法的對象。

  以上就是關于“哪些腳本語言支持API”的內容,希望對大家有用。更多資訊請關注學步園。學步園,您學習IT技術的優質平臺!

抱歉!評論已關閉.

奔驰宝马破解版下载 江西新十一选五多乐彩 河北十一选五选号工具 中国股票指数 河北河北快三开奖结果 黑龙江十一选五中奖规则 福彩东方6十1杀号 江苏11选5就是牛 新上市股票几天才能买 辽宁快乐11选5技巧规律 模拟炒股投资手机游戏 辽宁35选7好运彩规则 股票指数怎么看成分股 1分快3和值大小技巧准 体彩陕西十一选五开 黑龙江11选5号码推荐 江苏快3三同号遗漏