java9的新特性大家了解多少?
在Java 9中列出的新功能 -
1. Java平臺模塊系統(tǒng)
Java 9的定義功能是全新的模塊系統(tǒng)。當代碼庫越來越大時,創(chuàng)建復雜的“意大利面代碼”的可能性呈指數(shù)級增長。有兩個基本問題:真正封裝代碼是困難的,系統(tǒng)的不同部分(JAR文件)之間不存在顯式依賴的概念。每個公共類都可以被類路徑上的任何其他公共類訪問,導致無意使用不是公共API的類。此外,類路徑本身是有問題的:您如何知道所有必需的JAR是否存在,或者是否存在重復的條目?模塊系統(tǒng)解決了這兩個問題。
模塊化JAR文件包含一個額外的模塊描述符。在這個模塊描述符中,通過`require`語句表示對其他模塊的依賴關系。另外,`exports`語句控制哪些包可以被其他模塊訪問。所有未導出的軟件包默認封裝在模塊中。下面是一個模塊描述符的例子,它位于`module-info.java`中:
module blog { exports com.pluralsight.blog; requires cms;}我們可以將這些模塊可視化如下:
請注意,這兩個模塊都包含封裝的封裝,因為它們沒有導出(使用橙色屏蔽進行可視化)。沒有人可以意外地使用這些軟件包中的類。Java平臺本身也使用自己的模塊系統(tǒng)進行模塊化。通過封裝JDK內(nèi)部類,該平臺更加安全,并且變得更加容易。
當啟動模塊化應用程序時,JVM將驗證是否所有模塊都可以根據(jù)require語句來解析,這是脆弱類路徑的一大步。模塊允許您通過強大的封裝和顯式依賴性來更好地構(gòu)建應用程序。您可以通過本課程了解更多關于使用Java 9中的模塊的信息。
2.鏈接
當你擁有顯式依賴的模塊和模塊化的JDK時,會出現(xiàn)新的可能性。您的應用程序模塊現(xiàn)在聲明其依賴于其他應用程序模塊以及從JDK使用的模塊。為什么不使用這些信息創(chuàng)建最小的運行時環(huán)境,只包含運行應用程序所需的那些模塊?這是通過Java 9中的新jlink工具實現(xiàn)的。您可以創(chuàng)建一個針對您的應用程序進行優(yōu)化的最小運行時映像,而不是使用完全加載的JDK安裝來運行您的應用程序。
3. JShell:交互式Java REPL
許多語言已經(jīng)具有交互式的Read-Eval-Print-Loop,Java現(xiàn)在加入了這個俱樂部。您可以從控制臺啟動jshell,并直接開始鍵入并執(zhí)行Java代碼。jshell的即時反饋使其成為探索API和嘗試語言功能的絕佳工具。
測試Java正則表達式是jshell如何使您的生活更輕松的一個很好的例子。交互式外殼也使得教學環(huán)境和生產(chǎn)力提高,您可以在此網(wǎng)絡研討會中了解更多信息。在教人們?nèi)绾尉帉慗ava代碼的時候,不再需要解釋這個`public static void main(String [] args)`是什么意思。
4.改進了Javadoc
有時候,這些小事可能會造成很大的變化。你是否一直在用Google來找到正確的Javadoc頁面,就像我一樣?這不再是必要的。Javadoc現(xiàn)在在API文檔中包含了搜索權(quán)限。作為額外的好處,Javadoc輸出現(xiàn)在是HTML5兼容的。另外,您會注意到每個Javadoc頁面都包含有關類或接口來自哪個JDK模塊的信息。
5.收集工廠方法
通常你想在你的代碼中創(chuàng)建一個集合(例如一個List或者Set),并直接用一些元素來填充它。這導致重復性的代碼在你實例化集合,接著幾個`add`調(diào)用。在Java 9中,添加了幾個所謂的收集工廠方法:
Set<Integer> ints = Set.of(1, 2, 3);List<String> strings = List.of("first", "second");除了更短,更好閱讀,這些方法也使您不必選擇具體的收集實施。實際上,從工廠方法返回的集合實現(xiàn)針對您放入的元素數(shù)量進行了高度優(yōu)化。這是可能的,因為它們是不可變的:在創(chuàng)建后向這些集合中添加項目會導致“UnsupportedOperationException”。
6.流API改進
Streams API可以說是對Java標準庫長期以來最好的改進之一。它允許您創(chuàng)建集合的轉(zhuǎn)換的聲明式管道。使用Java 9,這只會變得更好。有四種新的方法添加到Stream接口:dropWhile,takeWhile,ofNullable。迭代方法得到一個新的重載,允許你提供一個關于什么時候停止迭代的謂詞:
1.IntStream.iterate(1, i -> i < 100, i -> i + 1).forEach(System.out::println);第二個參數(shù)是一個lambda,它返回true,直到IntStream中的當前元素變?yōu)?00.這個簡單的例子因此在控制臺上打印整數(shù)1直到99。
除了Stream本身的這些增加之外,Optional和Stream之間的集成也得到了改進。現(xiàn)在可以使用新的`stream`方法將Optional對象轉(zhuǎn)換為(可能為空)Stream :
1.Stream<Integer> s = Optional.of(1).stream();在構(gòu)建復雜的Stream流水線時將可選內(nèi)容轉(zhuǎn)換為Stream特別有用。
7.私人界面方法
Java 8為我們帶來了接口上的默認方法。一個接口現(xiàn)在可以包含行為而不是只有方法簽名。但是如果你在一個接口上有幾個默認的方法,那么會發(fā)生什么呢?通常情況下,您會重構(gòu)這些方法來調(diào)用包含共享功能的私有方法。但是默認方法不能是私有的。使用共享代碼創(chuàng)建另一個默認方法不是解決方案,因為此輔助方法成為公共API的一部分。使用Java 9,您可以將私有幫助器方法添加到接口來解決此問題:
public interface MyInterface { void normalInterfaceMethod(); default void interfaceMethodWithDefault() { init(); } default void anotherDefaultMethod() { init(); } // This method is not part of the public API exposed by MyInterface private void init() { System.out.println("Initializing"); }}如果您正在使用默認方法發(fā)展API,那么私有接口方法可以幫助您構(gòu)建其實現(xiàn)。
8. HTTP / 2
執(zhí)行HTTP調(diào)用的一種新方法是用Java 9來實現(xiàn)的。這個舊的`HttpURLConnection` API的替代品也支持WebSockets和HTTP / 2。一個警告:新的HttpClient API在Java 9中作為所謂的_incubator module_提供。這意味著API不能保證是100%最終的。不過,隨著Java 9的到來,您可以開始使用此API:
HttpClient client = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder(URI.create("http://www.google.com")) .header("User-Agent","Java") .GET() .build(); HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString());除了這個簡單的請求/響應模型外,HttpClient還提供了新的API來處理HTTP / 2特性,例如流和服務器推送。
9.多版本JAR
我們強調(diào)的最后一個特性對于圖書館維護者來說尤其是個好消息。當新版本的Java出現(xiàn)時,庫的所有用戶需要花費數(shù)年才能切換到這個新版本。這意味著庫必須與您想要支持的最舊版本的Java(例如,在許多情況下,Java 6或7)向后兼容。這實際上意味著你將無法長久地在庫中使用Java 9的新特性。幸運的是,多版本JAR特性允許您創(chuàng)建僅在特定Java版本上運行庫時使用的備用版本類別:
multirelease.jar├── META-INF│ └── versions│ └── 9│ └── multirelease│ └── Helper.class├── multirelease ├── Helper.class └── Main.class在這種情況下,可以在Java 9 上使用multirelease.jar ,而不是使用頂層multirelease.Helper類,使用`META-INF / versions / 9`下的那個。該Java 9特定版本的類可以使用Java 9功能和庫。同時,在較早的Java版本上使用這個JAR仍然有效,因為較早的Java版本只能看到頂層的Helper類。