程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻Java7的一些新特征和對劇本說話支撐API的引見

深刻Java7的一些新特征和對劇本說話支撐API的引見

編輯:關於JAVA

深刻Java7的一些新特征和對劇本說話支撐API的引見。本站提示廣大學習愛好者:(深刻Java7的一些新特征和對劇本說話支撐API的引見)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻Java7的一些新特征和對劇本說話支撐API的引見正文


1.switch前提語句中可以參加字符串了,完成辦法是應用了字符串的hashcode()值功課真實的值
2.增長了一種可以在字面量中應用的進制,二進制,經由過程在數字後面加“0b”或“0B”
3.在數字字面量中應用下劃線來分隔數字便利浏覽,不影響數值年夜小。根本准繩是前後都是數字的才可以湧現下劃線
4.java7對異常做了兩個修改:

  4.1.支撐在一個catch子句中同時捕捉多個異常,別的一個是在捕捉偏重新拋出異常時的異常類型加倍准確。java7中Throwable類增長addSuppressed辦法,當一個異常被拋出的時刻,能夠有其他異常由於該異常而被克制住,從而沒法正常拋出。這時候可以經由過程addSuppressed辦法把這些被克制的辦法記載上去,被克制的異常會湧現在拋出的異常的客棧信息中,也能夠經由過程getSuppressed辦法來獲得這些異常。如許做的利益是不會喪失任何異常,便利開辟人員測試。

public class ReadFile(){
     public void read(String filename) throws IOException {
         FileInputStream input = null;
         IOException readException = null;
         try {
             input = new FileInputStream(filename);
         } catch (IOException ex) {
             readException = ex;
         } finally {
             if (input != null) {
                 try {
                     input.close();
                 } catch (IOException ex) {
                     if (readException != null) {
                         readException.addSuppressed(ex);
                     } else {
                         readException = ex;
                     }
                 }
             }
             if (readException != null) {
                 throw readException;
             }
         }
     }
 }

這類做法的症結在於把finally語句中發生的異常經由過程addSuppressed辦法加到try語句發生的異常中。


java7改良了catch子句的語法,許可在個中指定多種異常,每一個異常類型之間應用“|”來分隔。須要留意的是在catch子句中聲明捕捉的這些異常,不克不及湧現反復的類型,也不許可個中的某個異常是別的一個異常參數的子類,不然會湧現編譯毛病(從小到年夜寫就沒成績)。假如在catch子句中聲清楚明了多個異常,那末異常參數的詳細類型是一切這些異常類型的最小上界。

  4.2應用try(請求資本){營業處置}來主動釋放資本,可以或許被try語句所治理的資本須要知足一個前提,那就是其java類要完成java.lang.AutoCloseable接口,不然會湧現編譯毛病。當須要釋放資本的時刻該接口的close辦法會被主動挪用。

5. 優化變長參數的辦法挪用:
j2se5.0中引入的一個新特征就是許可在辦法聲明中應用可變長度的參數。一個辦法的最初一個情勢參數可以被指定為代表隨意率性多個雷同類型的參數。在挪用的時刻,這些參數是以數組的情勢來傳遞的。在辦法體中也能夠依照數組的方法來援用這些參數。

6. java7引入了一個新的注解@SafeVarargs.假如開辟人員確信某個應用了可變長度參數的辦法,在與泛型類一路應用進不會湧現相似的情形,便可以用這個注解停止聲明。@SafeVarargs注解只能用在參數長度可變的辦法或結構辦法上,且辦法必需聲明為static或final,不然會湧現編譯毛病。一個辦法應用@SafeVarargs注解的條件是,開辟人員必需確保這個辦法的完成中對泛型類型參數的處置不會激發類型平安成績。

7.java中在java虛擬機中支撐一些劇本說話是經由過程劇本引擎。現實上劇本引擎治理器共支撐三種查找引擎方法,分離經由過程稱號,文件擴大名和MIME類型來完成。如

public void greet() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        if (engine == null) {
            throw new RuntimeException("找不到JavaScript說話履行引擎");
        }
        engine.eval("println('hello');");
    }

還可以經由過程getEngingByExtension("js")和getEngineByMimeType("text/javascript")來查找到。獲得劇本引擎ScriptEngine的對象後,經由過程其eval辦法可以履行一段代碼,並前往這段代碼的履行成果。

7.1 說話綁定:
劇本說話支撐api的一個很年夜優勢在於它標准了java說話與劇本說話之間的交互方法,使java說話編寫的法式可以與劇本之間停止雙向的辦法挪用和數據傳遞。數據傳遞是經由過程說話綁定對象來完成的。所謂的說話綁定對象就是一個簡略的哈希表,用來寄存和獲得須要同享的數據。一切數據都對應這個哈希表中的一個條目,是簡略的名值對。接口javax.script.Bingings界說了說話綁定對象的接口,它繼續自java.util.Map接口。一個劇本引擎在履行進程中能夠會應用多個說話綁定對象。分歧說話綁定對象的感化域分歧。在默許情形下,劇本引擎會供給多個說話綁定對象,用來寄存在履行進程中發生的全局對象等。ScriptEnging類供給了put和get辦法對劇本引擎中特定應用哉的默許說話綁定對象停止操作。法式可以直接應用這個默許的說話綁定對象,也能夠應用本身的說話綁定對象。在劇本履行進程中,可以將說話綁定對象算作是一個額定的變量映照表。在解析變量值的時刻,說話綁定對象中的稱號也會被斟酌在內。劇本 履行進程中發生的全局變量等外容,會湧現在說話綁定對象中。經由過程這類方法,就完成了Java與劇本說話之間的雙向數據傳遞。
如經由過程ScriptEngine的put辦法向劇本引擎默許的說話綁定對象中添加了一個名為“name”的字符串,接著在劇本中直接依據稱號來援用這個對象。異樣,在劇本中創立的全局變量“message”也能夠經由過程ScriptEnging的get辦法來獲得。如許就完成了Java法式與劇本之間的雙向數據傳遞。數據傳遞進程中的類型轉換是由劇本引擎來完成的,轉換規矩取決於詳細的說話的語法

public void useDefaultBinging() throws ScriptException {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("JavaScript");
        // ScriptEngine engine = getJavaScriptEnging();
        engine.put("name", "World");
        engine.eval("var message = 'hello,'+name;");
        engine.eval("println(message)");
        Object obj = engine.get("message");
        System.out.println(obj);
    }

在年夜多半情形下,應用ScriptEnging的put和get辦法就足夠了。假如僅應用put和get辦法,說話綁定對象自己關於開辟人員來講是通明的。在某些情形下,須要應用法式本身的說話綁定對象,好比說話綁定對象中包括了法式本身獨有的數據。假如願望應用本身的說話綁定對象,可以挪用劇本引擎的creatBingings辦法或創立一個javax.script.SimpleBingings對象,並傳遞給劇本引擎的eval辦法如:

public void useCustomBinding()throws ScriptException
    {
    ScriptEngine engine = getJavaScriptEngine();
    Bindings bindings = new SimpleBindings();
    bindings.put("hobby","play games");
    engine.eval("println('I like'+hobby);",bindings);
    }

經由過程eval辦法傳遞的說話綁定對象,僅在以後eval挪用中失效,其實不會轉變引擎默許的說話綁定對象

7.2 劇本履行高低文
與劇本引擎履行相干的別的一個主要接口是javax.script.ScriptContext,個中包括劇本引擎履行進程中的相干高低文信息,可以與JavaEE中servlet標准中的javax.servlet.ServletContext接口來停止類比。劇本引擎經由過程引高低文對象來獲得與劇本履行相干的信息,也許可開辟人員經由過程此對象來設置裝備擺設劇本引擎的行動。該高低對象中重要包括以下3類信息。
7.2.1 輸出與輸入
起首引見與劇本輸出和輸入相干的設置裝備擺設信息,個中包含劇本在履行頂用來讀取數據輸出的java.io.Reader對象和輸入准確內容和失足信息的java.io.Writer對象。在默許情形下,劇本的輸出輸入都產生在尺度掌握台中,假如願望把劇本的輸入寫入到文件 中,可使用以下代碼。經由過程setWriter辦法把劇本的輸入重定向到一個文件 中。經由過程ScriptContext的setReader和setErrorWriter辦法可以分離設置劇本履行時的數據輸出起源和發生毛病時失足信息的輸入 目標。

public void scriptToFile()throws IOException,ScriptException{
        ScriptEngine engine = getJavaScriptEngine();
        ScriptContext context = engine.getContext();
        context.setWriter(new FileWriter("output.txt"));
        engine.eval("println('hello world!');");
        }

7.2.2 自界說屬性

ScriptContext中也有與ServletContext中相似的獲得和設置屬性的辦法,即setAttribute和getAttribute.所分歧的是,ScriptContext中的屬性是有感化域之分的。分歧感化域的差別在於查找時的次序分歧,每一個感化域都以一個對應的整數表現其查找次序。該整數值越小,解釋查找時的次序越優先。優先級高的感化域中的屬性會隱蔽優先級低中的同名屬性。是以,設置屬性時須要顯式指定地點的感化域。在獲得屬性的時刻,便可選擇指定的感化域中查找,也能夠選擇依據感化域優先級主動停止查找。
不外劇本履行高低文完成 中包括的感化域是固定的。開辟人員不克不及隨便界說本身的感化域。經由過程ScriptContext的getScopes辦法可以獲得一切可用的感化域列表。SciptContext中事後界說了兩個感化域:常量ScriptContext.ENGINE_SCOPE表現的感化域對應的是以後的劇本引擎,而ScriptContext.GLOBAL_SCOPE表現的感化域對應的是從統一引擎工場中創立出來的一切劇本引擎對象。前者的優先級較高。以下例:

public void scriptContextAttribute(){
        ScriptEngine engine = getJavaScriptEnging();
        ScriptContext context = engine.getContext();
        context.setAttribute("name","World",ScriptContext.GLOBAL_SCOPE);
        context.setAttribute("name","Bob",ScriptContext.ENGINE_SCOPE);
        context.getAttribute("name");//值為Bob
        }

7.2.3 說話綁定對象

劇本履行高低文中的最初一類信息是說話綁定對象。說話綁定對象也是與感化域絕對應的。異樣的感化域優先級次序對說話綁定對象也實用。如許的優先級次序會對劇本履行時的變量解析發生影響。以下例:

public void scriptContextBindings()throws ScriptException
    {
    ScriptEngine engine = getJavaScriptEnging();
    ScriptContext context = engine.getContext();
    Bindings bindings1 = engine.createBindings();
    bindings1.put("name","World");
    context.setBindings(bindings1,ScriptContext.GLOBAL_SCOPE);
    Bindings bindings2 = engine.createBindings();
    bindings2.put("name","Bob");
    context.setBindings(bindings2,ScriptContext.ENGINE_SCOPE);
    engine.eval("println(name);");//成果為Bob
    }

還可以Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);

bindings.put("name","World")
engine.eval("println(name);");

7.3 劇本的編譯:
劇本說話普通是說明履行的。劇本引擎在運轉時須要先解析劇本以後再履行。普通來講,經由過程說明履行的方法運轉劇本的速度比編譯以後再運轉會慢一些。當一段劇本須要被屢次反復履行時,可以先對劇本停止編譯。編譯以後的劇本履行時不須要反復解析,可以進步履行效力。不是一切劇本引擎都支撐對劇本停止編譯。假如劇本引擎支撐這一特征,它會完成javax.script.Compilable接口來聲明這一點。劇本引擎的應用者可以應用這個才能來進步須要屢次履行的劇本的運轉效力。Java SE中自帶的JavaScript劇本引擎是支撐對劇本停止編譯的。
以下代碼中,Compilable接口的compile辦法用來對劇本代碼停止編譯,編譯的成果用javax.script.CompiledScript來表現。因為不是一切的劇本引擎都支撐Compilable接口,是以這裡須要用instanceof停止斷定。在run辦法中,經由過程CompiledScript的eval辦法便可以履行劇本。代碼中把一段劇本反復履行了100次,以此解釋編譯完的劇本在反復履行時的機能優勢。

public CompiledScript compile(String scriptText) throws ScriptException {
        ScriptEngine engine = getJavaScriptEngine();
        if (engine instanceof Compilable) {
            CompiledScript script = ((Compilable) engine).compile(scriptText);
        }
        return null;
    }

    public void run(String scriptText) throws ScriptException {
        CompiledScript script = compile(scriptText);
        if (script == null) {
            return;
        }
        for (int i = 0; i < 100; i++) {
            script.eval();
        }
    }

CompiledScript的eval辦法所接收的參數與ScriptEngine的eval辦法是雷同的。

7.4 劇本中辦法挪用
在劇本中,最多見的和最適用的就是辦法。有些劇本引擎許可應用者零丁挪用劇本中某個辦法。支撐這類辦法挪用方法的劇本引擎可以完成javax.script.Invocable接口。經由過程Invocable接口可以挪用劇本中的頂層辦法,也能夠挪用對象中的成員辦法。假如劇本中頂層辦法或對象中的成員辦法完成了Java中的接口,可以經由過程Invocable接口中的辦法來獲得劇本中響應的Java接口的完成對象。如許便可以在Java說話中界說接口,在劇本中完成接口。法式中應用該接口的其他部門代碼其實不曉得接口是由劇本來完成的。與Compilable接口一樣,ScriptEngine關於Invocable接口的完成也是可選的。
上面代碼經由過程Invocable接口的invokeFunction來挪用劇本中的頂層辦法,挪用時的參數會被傳遞給劇本中的辦法。由於JavaSE自帶的JavaScript劇本引擎完成了Invocable接口,所以這裡省去了對引擎能否完成了Invocalbe接口的斷定
在java中挪用劇本頂層辦法的示例:

public void invokeFunction()throws ScriptException,NoSuchMethodException{
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText ="function greet(name) { println('hello,'+name );}";
        engine.eval(scriptText);
        Invocable invocable=(Invocable)engine;
        invocable.invokeFunction("greet","World");
        }

假如被挪用辦法是劇本中對象的成員辦法,就須要應用invokeMethod辦法,以下面代碼中所示,代碼中getGreeting辦法是屬於對象obj的,在挪用的時刻須要把這個對象作為參數傳遞出來。

//在Java中挪用劇本對象的成員辦法的示例

public void inokeMethod()throws ScriptException,NoSuchMethodException
    {
    ScriptEngine engine = getJavaScriptEngine();
    String scriptText = "var obj={ getGreeting:function(name){return 'Hello,'+name;}};";
    engine.eval(scriptText);
    Invocable invocable = (Invocable)engine;
    Object scope = engine.get("obj");
    Object result = invocable.invokeMethod(scope,"getGreeting","Alxx");
    System.out.println(result);
    }

辦法invokeMethod與辦法invokeFunction用法差不多,差別在於invokeMethod要指定包括待挪用辦法的對象。

 

7.5 劇本中完成java接口

在有些劇本引擎中,可以在Java說話中界說接口,並在劇本中編寫接口的完成,如許法式中的其他部門可以只同Java接口交互,其實不須要關懷接口是由甚麼方法來完成的。鄙人面代碼中Greet是用Java界說的接口,個中包括一個getGreeting辦法。在劇本中完成這個接口,經由過程getInterface辦法可以獲得由劇本完成的這個接口的對象,並挪用個中的辦法。

public void useInterface() throws ScriptException {
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText = "function getGreeting(name){return 'Hello,'+name;}";
        engine.eval(scriptText);
        Invocable invocable = (Invocable) engine;
        Greet greet = invocable.getInterface(Greet.class);
        System.out.println(greet.getGreeting("World"));
    }

下面中的接口的完成是由劇本中的頂層辦法來完成的。異樣的,也能夠由劇本中對象的成員辦法來完成。關於這類情形,getInterface辦法別的一種重載情勢可以接收一個額定的參數來指定接話柄現地點的對象。

因為劇本說話的語法簡略和靈巧,異常實用於沒有或只要大批編程配景的用戶來應用,這些用戶可以經由過程劇本說話來定制法式的營業邏輯和用戶界面等,經由過程劇本說話可以在法式的易用性和靈巧性之間到達一個比擬好的均衡。好比劇本說話Lua就被普遍運用在游戲開辟中,用來對游戲的外部行動和用戶界面停止定制。

8. 反射API在為Java法式帶來靈巧性的同時,也發生了額定的機能價值,因為反射API的完成機制,關於雷同的操作,好比挪用一個辦法,用反射API來靜態完成比直接在源代碼中編寫的方法年夜概慢一到兩個數目級。跟著Java虛擬機完成的改良,反射API的機能曾經有了異常年夜的晉升。然則這類機能的差距是客不雅存在的,是以,在某些對機能請求比擬高的運用中,要慎用反射API。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved