1. 程式人生 > >Java 9 逆天的十大新特性

Java 9 逆天的十大新特性

在介紹Java 9 之前,我們先來看看Java 成立到現在的所有版本 。

        1990年初,最初被命名為Oak ;

        1995年5月23日,Java語言誕生;

        1996年1月,第一個JDK-JDK1.0誕生;

        1996年4月,10個最主要的作業系統供應商申明將在其產品中嵌入Java技術;

        1996年9月,約8.3萬個網頁應用了Java技術來製作;

        1997年2月18日,JDK1.1釋出;

        1997年4月2日,JavaOne會議召開,參與者逾一萬人,創當時全球同類會議紀錄;

        1997年9月,JavaDeveloperConnection 社群成員超過十萬;

        1998年2月,JDK1.1被下載超過2,000,000次;

        1998年12月8日,Java 2企業平臺J2EE釋出;

        1999年6月,SUN公司釋出Java三個版本:標準版(J2SE)、企業版(J2EE)和微型版(J2ME);

        2000年5月8日,JDK1.3釋出;

        2000年5月29日,JDK1.4釋出;

        2001年6月5日,Nokia宣佈到2003年將出售1億部支援Java的手機;

        2001年9月24日,J2EE1.3釋出;

        2002年2月26日,J2SE1.4釋出,此後Java的計算能力有了大幅提升;

       2004年9月30日,J2SE1.5釋出,成為Java語言發展史上的又一里程碑。為了表示該版本的重要性,J2SE1.5更名為Java SE 5.0;

       2005年6月,JavaOne大會召開,SUN公司公開Java SE 6。此時,Java的各種版本已經更名,以取消其中的數字“2”:J2EE更名為Java EE,J2SE更名為Java SE,J2ME更名為Java ME;

       2006年12月,SUN公司釋出JRE6.0;

       2009年4月20日,甲骨文以74億美元的價格收購SUN公司,取得java 的版權,業界傳聞說這對Java 程式設計師是個壞訊息(其實恰恰相反);

       2010年11月,由於甲骨文對Java 社群的不友善,因此Apache 揚言將退出JCP;

       2011年7月28日,甲骨文釋出Java SE 7;

       2014年3月18日,甲骨文發表Java SE 8;

       2017年7月,甲骨文發表Java SE 9。

1 modularity System 模組系統

         Java 9 中主要的變化是已經實現的模組化系統。

        Modularity 提供了類似於OSGI 框架的功能,模組之間存在相互的依賴關係,可以匯出一個公共的API,並且隱藏實現的細節,Java 提供該功能的主要的動機在於,減少記憶體的開銷,在JVM 啟動的時候,至少會有30~60MB的記憶體載入,主要原因是JVM 需要載入rt.jar,不管其中的類是否被classloader 載入,第一步整個jar都會被JVM載入到記憶體當中去,模組化可以根據模組的需要載入程式執行需要的class。

        在引入了模組系統之後,JDK 被重新組織成 94 個模組。Java 應用可以通過新增的 jlink 工具,創建出只包含所依賴的 JDK 模組的自定義執行時映象。這樣可以極大的減少 Java 執行時環境的大小。使得JDK 可以在更小的裝置中使用。採用模組化系統的應用程式只需要這些應用程式所需的那部分JDK 模組,而非是整個JDK 框架了。

2 HTTP/2

       JDK 9 之前提供HttpURLConnection API來實現Http訪問功能,但是這個類基本很少使用,一般都會選擇Apache的Http Client,此次在Java 9的版本中引入了一個新的package:java.net.http,裡面提供了對Http 訪問很好的支援,不僅支援Http1.1 而且還支援HTTP2(什麼是HTTP2?請參見HTTP2的時代來了...),以及WebSocket,據說效能特別好。

注意:新的 HttpClient API 在 Java 9 中以所謂的孵化器模組交付。也就是說,這套 API 不能保證 100% 完成。

3 JShell

        用過Python的童鞋都知道,Python 中的讀取-求值-列印迴圈( Read-Evaluation-Print Loop )很方便。它的目的在於以即時結果和反饋的形式。

        java 9 引入了jshell 這個互動性工具,讓Java 也可以像指令碼語言一樣來執行,可以從控制檯啟動 jshell ,在 jshell 中直接輸入表示式並檢視其執行結果。當需要測試一個方法的執行效果,或是快速的對錶達式進行求值時,jshell 都非常實用。

        除了表示式之外,還可以建立 Java 類和方法。jshell 也有基本的程式碼完成功能。我們在教人們如何編寫 Java 的過程中,不再需要解釋 “public static void main(String [] args)” 這句廢話。

4 不可變集合工廠方法

        Java 9增加了List.of()、Set.of()、Map.of()和Map.ofEntries()等工廠方法來建立不可變集合。

        List strs = List.of("Hello", "World");

        List strs List.of(1, 2, 3);

        Set strs = Set.of("Hello", "World");

        Set ints = Set.of(1, 2, 3);

        Map maps = Map.of("Hello", 1, "World", 2);

      除了更短和更好閱讀之外,這些方法也可以避免您選擇特定的集合實現。在建立後,繼續新增元素到這些集合會導致 “UnsupportedOperationException” 。

5 私有介面方法

        Java 8 為我們提供了介面的預設方法和靜態方法,介面也可以包含行為,而不僅僅是方法定義。

       預設方法和靜態方法可以共享介面中的私有方法,因此避免了程式碼冗餘,這也使程式碼更加清晰。如果私有方法是靜態的,那這個方法就屬於這個介面的。並且沒有靜態的私有方法只能被在介面中的例項呼叫。

interface InterfaceWithPrivateMethods {

    private static String staticPrivate() {

        return "static private";

    }

    private String instancePrivate() {

        return "instance private";

    }

    default void check() {    

        String result = staticPrivate();

        InterfaceWithPrivateMethods pvt = new InterfaceWithPrivateMethods() {

            // anonymous class 匿名類

        };

        result = pvt.instancePrivate();

    }

}

6 HTML5 風格的Java 幫助文件

        Java 8 之前的版本生成的Java 幫助文件是在HTML 4中。在Java 9中,Javadoc 的輸出現在符合相容 HTML5 標準。現在HTML 4是預設的輸出標記語言,但是在之後釋出的JDK中,HTML 5將會是預設的輸出標記語言。

        Java 幫助文件還是由三個框架組成的結構構成,這是不會變的,並且以HTML 5輸出的Java幫助文件也保持相同的結構。每個 Javadoc 頁面都包含有關 JDK 模組類或介面來源的資訊。

7 多版本相容 JAR

        當一個新版本的 Java 出現的時候,你的庫使用者要花費很長時間才會切換到這個新的版本。這就意味著庫要去向後相容你想要支援的最老的 Java 版本 (許多情況下就是 Java 6 或者 7)。這實際上意味著未來的很長一段時間,你都不能在庫中運用 Java 9 所提供的新特性。幸運的是,多版本相容 JAR 功能能讓你建立僅在特定版本的 Java 環境中執行庫程式時選擇使用的 class 版本:

multirelease.jar

├── META-INF

│   └── versions

│       └── 9

│           └── multirelease

│               └── Helper.class

├── multirelease

├── Helper.class

└── Main.class

        在上述場景中, multirelease.jar 可以在 Java 9 中使用, 不過 Helper 這個類使用的不是頂層的 multirelease.Helper 這個 class, 而是處在“META-INF/versions/9”下面的這個。這是特別為 Java 9 準備的 class 版本,可以運用 Java 9 所提供的特性和庫。同時,在早期的 Java 諸版本中使用這個 JAR 也是能執行的,因為較老版本的 Java 只會看到頂層的這個 Helper 類。

8 統一 JVM 日誌

        Java 9 中 ,JVM 有了統一的日誌記錄系統,可以使用新的命令列選項-Xlog 來控制 JVM 上 所有元件的日誌記錄。該日誌記錄系統可以設定輸出的日誌訊息的標籤、級別、修飾符和輸出目標等。

9 java 9 的垃圾收集機制

        Java 9 移除了在 Java 8 中 被廢棄的垃圾回收器配置組合,同時把G1 設為預設的垃圾回收器實現。替代了之前預設使用的Parallel GC,對於這個改變,evens的評論是醬紫的:這項變更是很重要的,因為相對於Parallel來說,G1會在應用執行緒上做更多的事情,而Parallel幾乎沒有在應用執行緒上做任何事情,它基本上完全依賴GC 執行緒完成所有的記憶體管理。這意味著切換到G1將會為應用執行緒帶來額外的工作,從而直接影響到應用的效能

10 I/O 流新特性

        java.io.InputStream 中增加了新的方法來讀取和複製 InputStream 中包含的資料。

        readAllBytes:讀取 InputStream 中的所有剩餘位元組。

        readNBytes: 從 InputStream 中讀取指定數量的位元組到陣列中。

        transferTo:讀取 InputStream 中的全部位元組並寫入到指定的 OutputStream 中 。

除了上面這些以外,還有以下這麼多的新特性,不再一一介紹。

    102: Process API Updates

    110: HTTP 2 Client

    143: Improve Contended Locking

    158: Unified JVM Logging

    165: Compiler Control

    193: Variable Handles

    197: Segmented Code Cache

    199: Smart Java Compilation, Phase Two

    200: The Modular JDK

    201: Modular Source Code

    211: Elide Deprecation Warnings on Import Statements

    212: Resolve Lint and Doclint Warnings

    213: Milling Project Coin

    214: Remove GC Combinations Deprecated in JDK 8

    215: Tiered Attribution for javac

    216: Process Import Statements Correctly

    217: Annotations Pipeline 2.0

    219: Datagram Transport Layer Security (DTLS)

    220: Modular Run-Time Images

    221: Simplified Doclet API

    222: jshell: The Java Shell (Read-Eval-Print Loop)

    223: New Version-String Scheme

    224: HTML5 Javadoc

    225: Javadoc Search

    226: UTF-8 Property Files

    227: Unicode 7.0

    228: Add More Diagnostic Commands

    229: Create PKCS12 Keystores by Default

    231: Remove Launch-Time JRE Version Selection

    232: Improve Secure Application Performance

    233: Generate Run-Time Compiler Tests Automatically

    235: Test Class-File Attributes Generated by javac

    236: Parser API for Nashorn

    237: Linux/AArch64 Port

    238: Multi-Release JAR Files

    240: Remove the JVM TI hprof Agent

    241: Remove the jhat Tool

    243: Java-Level JVM Compiler Interface

    244: TLS Application-Layer Protocol Negotiation Extension

    245: Validate JVM Command-Line Flag Arguments

    246: Leverage CPU Instructions for GHASH and RSA

    247: Compile for Older Platform Versions

    248: Make G1 the Default Garbage Collector

    249: OCSP Stapling for TLS

    250: Store Interned Strings in CDS Archives

    251: Multi-Resolution Images

    252: Use CLDR Locale Data by Default    

    253: Prepare JavaFX UI Controls & CSS APIs for Modularization

    254: Compact Strings

    255: Merge Selected Xerces 2.11.0 Updates into JAXP

    256: BeanInfo Annotations

    257: Update JavaFX/Media to Newer Version of GStreamer

    258: HarfBuzz Font-Layout Engine

    259: Stack-Walking API

    260: Encapsulate Most Internal APIs

    261: Module System

    262: TIFF Image I/O

    263: HiDPI Graphics on Windows and Linux

    264: Platform Logging API and Service

    265: Marlin Graphics Renderer

    266: More Concurrency Updates

    267: Unicode 8.0

    268: XML Catalogs

    269: Convenience Factory Methods for Collections

    270: Reserved Stack Areas for Critical Sections

    271: Unified GC Logging

    272: Platform-Specific Desktop Features

    273: DRBG-Based SecureRandom Implementations

    274: Enhanced Method Handles

    275: Modular Java Application Packaging

    276: Dynamic Linking of Language-Defined Object Models

    277: Enhanced Deprecation

    278: Additional Tests for Humongous Objects in G1

    279: Improve Test-Failure Troubleshooting        

    280: Indify String Concatenation

    281: HotSpot C++ Unit-Test Framework

    282: jlink: The Java Linker

    283: Enable GTK 3 on Linux

    284: New HotSpot Build System

    285: Spin-Wait Hints

    287: SHA-3 Hash Algorithms

    288: Disable SHA-1 Certificates

    289: Deprecate the Applet API    

    290: Filter Incoming Serialization Data

    292: Implement Selected ECMAScript 6 Features in Nashorn

    294: Linux/s390x Port

    295: Ahead-of-Time Compilation