新的Java 9功能一目瞭然

java那些事2017-09-25 09:50:44

過去3年多,我們一直在等待這一刻,但現在終於到了 - Java 9已經發布了。在本文中,Henning Schwentner介紹了新版本的功能。

新的模塊化系統:Java中的項目拼圖9

使用版本8,Java確實獲得了很多新功能,其中Lambdas的支持肯定是最大的影響。此外,對集合和新的日期時間API的啟用的批量操作改進了Java開發人員的日常生活。然而,長期以來想要的功能尚未成為Java 8,併成為新發布的Java 9版本的商標- 使用Project Jigsaw進行模塊化。

項目拼圖解決了迄今為止影響Java的兩個問題,即“JAR地獄”,並且在類之上缺少強大的封裝機制。從一開始,Java就有了一個包構造。一個類可以包含一個包中的兩個可見性級別之一。無論是公開的,在這種情況下,可以從任何地方訪問該類。如果它不是公共的,它只能從包中進行訪問。

但是包不能嵌套。因此,您或者擁有非結構化的“大泥巴” - 包裹或僅由公共課程組成的包。JAR(Java Archives)只是一組公共類文件加數據。它們不是組件,不提供封裝。因此,它們沒有接口,或者JAR的接口是JAR所包含的接口,因為由於缺少封裝,它不能從外部訪問中隱藏任何內容。

第9版給Java定義模塊的可能性。一個模塊是一個命名的,自描述的程序組件,由一個或多個包(和數據)組成。模塊可以定義如清單1所示。

模塊 de module .a { exports de。module .a.paket.x;}模塊 de module .b { exports de。module .a.paket.y; 出口德 module .a.paket.z;}模塊 de module .c { requires de。模塊 .a 需要 de 模塊 .b} 
該接口定義指示模塊向外部世界提供哪些包(使用關鍵字exports)以及外部需要哪些模塊(需要關鍵字)。注意:這不是前一句中的錯字; 一個模塊導出包,但需要模塊。這可能會令人困惑,因為軟件包和模塊通常具有相同或非常相似的名稱。未明確導出的模塊的所有軟件包只能在模塊中使用。如果您嘗試從模塊外部訪問它們,則會發生編譯器錯誤。

使用模塊化JAR作為模塊

現在我們已經看到了如何聲明一個模塊,讓我們回答另一個問題:我們在哪裡編寫模塊聲明?該約定表示您在名為module-info.java的源代碼文件中聲明它,並將其放在模塊的文件層次結構的根目錄下。然後,編譯器將其轉換為文件module-info.class。名稱“module-info”包含連字符,因為它是一個無效的類名。這樣,現有的代碼就不會被損壞。然後將Java文件稱為模塊聲明和類文件模塊描述符。

如果您以這種方式聲明瞭一個模塊,則可以從中創建一個模塊化的JAR。它的結構就像一個常規的JAR文件,區別在於它的根目錄下有一個module-info.class文件。這樣的模塊化JAR可以用作模塊。由於向下兼容的原因,它也可以用作經典的JAR文件和類路徑。那麼module-info.class就被忽略了。說到類路徑:通過引入模塊概念,它是由一個替代ModulePath進行。在模塊路徑中,您可以指定在文件系統中找到特定模塊的位置。

在過去,有一個類路徑,一堆JAR無序,可以不可控制地使用對方。此外,JAR內的所有內容都可以訪問。現在我們可以使用模塊機制來明確定義哪個模塊應該使用哪些模塊。這使得可以使用相同庫並行的多個版本。例如,模塊A可以使用版本1中的庫,版本2中的模塊B,最後,模塊C可以使用兩個模塊A和B.

使用Java 9的域驅動設計

通過模塊概念,可以更好地表達軟件架構。例如,層可以表示為模塊,並且它們的界面可以被清楚地定義。編譯器可以至少部分地檢測並防止架構違規。我們舉一個銀行應用程序的例子,設計用域驅動的設計(清單2和圖1)。 

module de.wps.bankprogramm.domainLayer { exports de.wps.bankprogramm.domainLayer.valueObject; 出口 de.wps.bankprogramm.domainLayer.entity;}module de.wps.bankprogramm.infrastructurelayer { exports de.wps.bankprogramm.infrastructureLayer.database;}module de.wps.bankprogramm.applicationLayer { requires de.wps.bankprogramm.infrastructureLayer; 需要 de.wps.bankprogramm.domainLayer; 出口 de.wps.bankprogramm.applicationLayer.repositories;}module de.wps.bankprogramm.uiLayer { requires de.wps.bankprogramm.domainLayer; 需要 de.wps.bankprogramm.applicationLayer;} 
系統的四層被實現為模塊。專用邏輯層(即模塊domainLayer)的模塊被聲明為與其他模塊沒有依賴關係。我們不想依賴技術代碼來汙染我們的業務代碼。它包含一個用於我們系統的實體的包,一個用於它的值對象。的儲存庫,反過來,可以在基礎設施層(模塊infrastructureLayer)。因此,在這個設計中,它們被插入到應用層模塊(applicationLayer)中。根據上述聲明,可以訪問基礎設施和業務邏輯層。

用戶界面層(uiLayer模塊)可以訪問用戶邏輯和應用層。使用數據庫訪問代碼的包將導致編譯器錯誤,因為它在基礎設施包中,並且沒有在uiLayer的要求中指定。存儲庫到應用程序層的分配在架構上並不完全清晰,而是在這裡完成,以避免使示例過於複雜。

將JDK切成塊

模塊機制對許多項目很有興趣,特別是JDK本身。這是項目名稱,拼圖來自的地方。並用這個拼圖Java應該分為模塊。到目前為止,整個JRE必須始終交付,即使只運行沒有GUI或不訪問數據庫的小程序。使用Java 9,JRE和JDK分解為模塊本身。這允許每個程序定義它需要什麼,減少內存使用和提高性能。

Java標準模塊包括java.base,java.sql,java.desktop和java.xml。基本模塊java.base總是隱式包含 - 就像包java.lang不需要單獨導入一樣。模塊java.base將包含java.lang,java.math和java.io包。對於JDK本身的模塊,JAR文件不夠,因為它們也必須包含本機代碼。因此,這裡介紹了所謂的JMOD文件。Java的首席架構師Mark Reinhold的直接引用:“JMOD文件是類固醇的JAR文件”。項目拼圖當然是Java 9帶來的巨大變化,也是其主要功能。但還有一些其他功能將使開發人員的生活更輕鬆。

Java 9中還會發生什麼

許多編程語言都有一個讀取 - 打印循環(REPL),即一種直接執行該語言代碼並輸出結果的命令行。Java在標準的JDK中沒有這樣的東西。有第三方產品,如BeanShell或Java REPL,以及IntelliJ IDEA插件。Kulla項目將JShell介紹給JDK - 官方的Java版本REPL。這提供了希望Java將更容易學習。交互式模式可以使程序員比經典的寫/編譯/執行週期快得多的反饋。

使用Java 9,現在有命令行的CLI程序jshell。還提供了一個API,以便其他應用程序可以使用此功能。對於要在Eclipse中使用JShell的IDE製造商來說,這是特別有趣的,NetBeans和Co.可以安裝。

支持Unicode

存在Unicode以對不同語言的字符進行編碼。該標準不斷擴展,最後兩個版本7.0和8.0尚不支持Java。Unicode 7.0包含對雙向文本的改進,即包含拉丁字母和非拉丁字符的部分。

例如,使用8.0版,emojis是以不同膚色和新的面孔,如聖誕節母親的表情擴展的。此外,單獨的JEP(第226號)允許您以UTF-8保存屬性文件。以前只支持ISO 8859-1作為編碼。該資源包API擴展用於這一目的。

輕鬆創建收藏

使用數組一次定義幾個對象並不難。

String [] firstnames = { “Joe”,“Bob”,“Bill” }; 
不幸的是,這不是很容易收藏,但是。要創建一個小的,不可改變的集合,必須構造和分配它,然後添加元素,最後構建一個周圍的包裝器。

列表firsnamesList = new ArrayList <>();firstnamesList。add(“Joe”);firstnamesList。add(“Bob”);firstnamesList。add(“Bill”);firstnamesList = Collections.unmodifiableList(firstnamesList); 
我們沒有一行代碼,而是一行五行。此外,它不能表達為單個表達式。有幾種選擇,例如Arrays.asList(),但是如果要定義大量的值,則需要很長時間:

設置 firstnamesQuantity = Collections.unmodifiableSet( new HashSet(Arrays.asList(“Joe”,“Bob”,“Bill”))); 
Java 9因此引入了方便的方法,這使得類似的事情更容易表達。

列表 firsnamesList = 列表 .of( “ 喬”,“鮑勃”,“比爾”); 
使用變量,可以將不同數量的參數傳輸到這些工廠方法。此功能可用於集合和列表,也可用於Map的類似形式。由於Java 8中接口的方法實現,所謂的默認方法,可以直接在List,Set和Map的接口內定義這些方便方法。

Java 9中的HTTP / 2支持

HTTP,用於傳輸網頁的協議,早在1997年就被採用在目前的1.1版本中。直到2015年,新版本2才成為標準。新版本的目標是減少延遲,從而允許更快地加載網頁。這是通過各種技術實現的:

標題壓縮 
服務器推送 
流水線 
通過TCP連接複用多個HTTP請求 
同時,與HTTP 1.1的兼容性仍然保持不變。大部分語法甚至保持不變; 例如,方法(GET,PUT,POST等),URI,狀態代碼和頭字段。

Java將具有實現JEP 110的HTTP / 2開箱即用的支持。此外,過時的HttpURLConnection -API正在被替換。它是在HTTP 1.0的時代創建的,並使用了協議無關的方法。這適合九十年代,因為目前還不確定HTTP的成功率。然而,如今,對Gopher的支持並不重要。ALPN也得到支持。在新世界,您可以使用當代Fluent-API。

HttpResponse response = HttpRequest .create(new URI(“http://www.javamagazin.de”) 。體(一個人()) 。GET() 。發送(); 
所得到的HTTP響應可用於查詢狀態代碼和內容:

int statusCode = response .responseCode();String body = response .body(asString()); 
減少內存消耗與緊湊的字符串

從版本1開始,Java中的字符串將使用java.lang.String類顯示。從一開始,這個類包含一個char數組。該數據類型在Java中佔用兩個字節。這樣可以輕鬆地在UTF-16中顯示字符,而不僅僅是支持拉丁字母。然而,許多應用程序只使用來自Latin-1編碼的字符,它只需要一個字節。在這種情況下,每隔一個字節是空的,並且浪費了內存空間。

因此,JEP 254引入了String類的一個實現,它包含一個字節數組加上一個編碼字段而不是一個字符數組。編碼字段指定字符串是否包含佔用每個兩個字節的UTF-16字符的經典序列,或者每個佔用一個字節的拉丁字母序列。創建相應字符串的編碼應由字符串內容自動識別。

這個優化的愉快之處在於您可以自動從中受益。實際上,它只是一個實現細節,與舊的Java版本保持100%的兼容性。因此,使用許多字符串的應用程序將通過簡單地安裝最新版本的Java來顯著減少其內存需求。除了String類之外,還調整了相關類(如StringBuilder和StringBuffer)以及HotSpot VM。

Java中的JavaDoc增強功能9

到目前為止,JavaDoc只能在4.01的過時版本中生成HTML。使用Java 9,可以創建HTML5。因此,javadoc命令是指定要生成的HTML代碼的版本。相關聯的JEP 224的明確的非目標是消除三個幀結構。希望這將在未來的版本中完成。此外,生成的HTML頁面將被提供有用於搜索某些Java元素的搜索機制。然後根據“模塊”,“包”或“類型”對結果進行分類。

自動縮放HiDPI圖形

在Mac上,JDK已經支持視網膜顯示,但在Linux和Windows上,它並沒有。在那裡,Java程序在當前的高分辨率屏幕上可能看起來很小,不能使用它們。這是因為像素用於這些系統的大小計算 - 無論像素實際有多大。畢竟,高分辨率顯示器的有趣部分是像素非常小。

JEP 263以這樣的方式擴展了JDK,即Windows和Linux也考慮到像素的大小。為此,使用比現在更多的現代API:Direct2D for Windows和GTK +而不是Xlib for Linux。圖形,窗口和文本由此自動縮放。JEP 251還提供處理多分辨率圖像的能力,即包含不同分辨率的相同圖像的文件。根據相應屏幕的DPI度量,然後以適當的分辨率使用圖像。

Java 9還有什麼?

像任何其他Java版本一樣,Java 9包含許多次要的細節和更新。這些包括:

將ARM處理器升級到64位層級的新型ARM架構AArch64現在得到了支持。 
從版本1.2開始,Java使用自己的專有格式來存儲加密密鑰:JKS。JEP 229新增了Java中的標準文件格式PKCS12。 
Java 8的更新40引入了垃圾收集器G1(垃圾回收)。Java 9現在將G1提升到標準的垃圾收集器狀態。 
在Java 8之前,Image I / O框架不支持圖像格式TIFF。這將與JEP 262進行更改,javax.imageio將相應地進行擴展。 
使用Rhino,Java具有JavaScript執行環境。對於IDE和類似的工具,JEP 236公開釋放先前僅在內部可用的解析器API,以訪問AST。 
前景:Java 9之後?

原來這篇文章最初應該是:“2016年9月,新的Java版本9將被髮布”。現在一年以後的事實肯定不會太糟糕,因為許多變化屬於“家務”類別。

因此,終於支持當前版本的Unicode和HTTP標準。還有一些微小的變化,使開發人員的生活變得更加容易,比如更方便的創建集合和實現緊湊的字符串。

最重要的功能是項目拼圖的模塊概念。主要項目和需要較小內存佔用的項目都是關鍵因素,將受益於這一發展。主要項目受益於JAR-hell的問題一方面使用ModulePath解決,另一方面是因為這些系統的架構可以用模塊更清楚地表達出來。內存敏感項目受益,因為JDK本身分為多個模塊,不再需要整體加載。


https://weiwenku.net/d/102789991