面試官問我Java8~14的有哪些重要的新特性,我哭了~~~

你們好,我是Guide哥!這篇文章來自讀者的投稿,通過了兩次較大的改動,兩週的完善終於完成。Java 8新特性見這裏:Java8新特性最佳指南html

Guide 哥:別人家的特性都用了幾年了,我 Java 纔出來,哈哈!真實!java

Java9

發佈於 2017 年 9 月 21 日 。做爲 Java8 以後 3 年半才發佈的新版本,Java 9 帶 來了不少重大的變化其中最重要的改動是 Java 平臺模塊系統的引入,其餘還有諸如集合、Stream 流linux

Java 平臺模塊系統

Java 平臺模塊系統,也就是 Project Jigsaw,把模塊化開發實踐引入到了 Java 平臺中。在引入了模塊系統以後,JDK 被從新組織成 94 個模塊。Java 應用能夠經過新增的 jlink 工具,建立出只包含所依賴的 JDK 模塊的自定義運行時鏡像。這樣能夠極大的減小 Java 運行時環境的大小。git

Java 9 模塊的重要特徵是在其工件(artifact)的根目錄中包含了一個描述模塊的 module-info.class 文 件。 工件的格式能夠是傳統的 JAR 文件或是 Java 9 新增的 JMOD 文件。github

Jshell

jshell 是 Java 9 新增的一個實用工具。爲 Java 提供了相似於 Python 的實時命令行交互工具。web

在 Jshell 中能夠直接輸入表達式並查看其執行結果算法

集合、Stream 和 Optional

  • 增長 了 List.of()Set.of()Map.of()Map.ofEntries()等工廠方法來建立不可變集合,好比 List.of("Java", "C++");Map.of("Java", 1, "C++", 2);(這部份內容有點參考 Guava 的味道)
  • Stream 中增長了新的方法 ofNullabledropWhiletakeWhileiterate 方法。 Collectors 中增長了新的方法 filteringflatMapping
  • Optional 類中新增了 ifPresentOrElseorstream 等方法

進程 API

Java 9 增長了 ProcessHandle 接口,能夠對原生進程進行管理,尤爲適合於管理長時間運行的進程shell

平臺日誌 API 和服務

Java 9 容許爲 JDK 和應用配置一樣的日誌實現。新增了 System.LoggerFinder 用來管理 JDK 使 用的日誌記錄器實現。JVM 在運行時只有一個系統範圍的 LoggerFinder 實例。json

咱們能夠經過添加本身的 System.LoggerFinder 實現來讓 JDK 和應用使用 SLF4J 等其餘日誌記錄框架。bootstrap

反應式流 ( Reactive Streams )

  • 在 Java9 中的 java.util.concurrent.Flow 類中新增了反應式流規範的核心接口
  • Flow 中包含了 Flow.PublisherFlow.SubscriberFlow.SubscriptionFlow.Processor 等 4 個核心接口。Java 9 還提供了 SubmissionPublisher 做爲 Flow.Publisher 的一個實現。

變量句柄

  • 變量句柄是一個變量或一組變量的引用,包括靜態域,非靜態域,數組元素和堆外數據結構中的組成部分等
  • 變量句柄的含義相似於已有的方法句柄 MethodHandle
  • 由 Java 類 java.lang.invoke.VarHandle 來表示,可使用類 java.lang.invoke.MethodHandles.Lookup 中的靜態工廠方法來建立 VarHandle 對 象

改進方法句柄(Method Handle)

  • 方法句柄從 Java7 開始引入,Java9 在類 java.lang.invoke.MethodHandles 中新增了更多的靜態方法來建立不一樣類型的方法句柄

其它新特性

  • 接口私有方法 :Java 9 容許在接口中使用私有方法
  • try-with-resources 加強 :在 try-with-resources 語句中可使用 effectively-final 變量(什麼是 effectively-final 變量,見這篇文章 ilkinulas.github.io/programming…
  • CompletableFuture 中增長了幾個新的方法(completeAsyncorTimeout 等)
  • Nashorn 引擎的加強 :Nashorn 從 Java8 開始引入的 JavaScript 引擎,Java9 對 Nashorn 作了些加強,實現了一些 ES6 的新特性
  • I/O 流的新特性 :增長了新的方法來讀取和複製 InputStream 中包含的數據
  • 改進應用的安全性能 :Java 9 新增了 4 個 SHA- 3 哈希算法,SHA3-22四、SHA3-25六、SHA3-384 和 S HA3-512
  • ......

Java10

發佈於 2018 年 3 月 20 日,最知名的特性應該是 var 關鍵字(局部變量類型推斷)的引入了,其餘還有垃圾收集器改善、GC 改進、性能提高、線程管控等一批新特性

var 關鍵字

  • 介紹 :提供了 var 關鍵字聲明局部變量: var list = new ArrayList<String>(); // ArrayList<String>
  • 侷限性 :只能用於帶有構造器的 局部變量和 for 循環中

Guide 哥:實際上 Lombok 早就體用了一個相似的關鍵字,使用它能夠簡化代碼,可是可能會下降程序的易讀性、可維護性。通常狀況下,我我的都不太推薦使用。

不可變集合

list,set,map 提供了靜態方法copyOf()返回入參集合的一個不可變拷貝(如下爲 JDK 的源碼)

static <E> List<E> copyOf(Collection<? extends E> coll) {
    return ImmutableCollections.listCopy(coll);
}
複製代碼

java.util.stream.Collectors中新增了靜態方法,用於將流中的元素收集爲不可變的集合

Optional

  • 新增了 orElseThrow()方法來在沒有值時拋出異常

並行全垃圾回收器 G1

從 Java9 開始 G1 就了默認的垃圾回收器,G1 是以一種低延時的垃圾回收器來設計的,旨在避免進行 Full GC,可是 Java9 的 G1 的 FullGC 依然是使用單線程去完成標記清除算法,這可能會致使垃圾回收期在沒法回收內存的時候觸發 Full GC。

爲了最大限度地減小 Full GC 形成的應用停頓的影響,從 Java10 開始,G1 的 FullGC 改成並行的標記清除算法,同時會使用與年輕代回收和混合回收相同的並行工做線程數量,從而減小了 Full GC 的發生,以帶來更好的性能提高、更大的吞吐量。

應用程序類數據共享

在 Java 5 中就已經引入了類數據共享機制 (Class Data Sharing,簡稱 CDS),容許將一組類預處理爲共享歸檔文件,以便在運行時可以進行內存映射以減小 Java 程序的啓動時間,當多個 Java 虛擬機(JVM)共享相同的歸檔文件時,還能夠減小動態內存的佔用量,同時減小多個虛擬機在同一個物理或虛擬的機器上運行時的資源佔用

Java 10 在現有的 CDS 功能基礎上再次拓展,以容許應用類放置在共享存檔中。CDS 特性在原來的 bootstrap 類基礎之上,擴展加入了應用類的 CDS (Application Class-Data Sharing) 支持。其原理爲:在啓動時記錄加載類的過程,寫入到文本文件中,再次啓動時直接讀取此啓動文本並加載。設想若是應用環境沒有大的變化,啓動速度就會獲得提高

其餘特性

  • 線程-局部管控:Java 10 中線程管控引入 JVM 安全點的概念,將容許在不運行全局 JVM 安全點的狀況下實現線程回調,由線程自己或者 JVM 線程來執行,同時保持線程處於阻塞狀態,這種方式使得中止單個線程變成可能,而不是隻能啓用或中止全部線程

  • 備用存儲裝置上的堆分配:Java 10 中將使得 JVM 可以使用適用於不一樣類型的存儲機制的堆,在可選內存設備上進行堆內存分配

  • 統一的垃圾回收接口:Java 10 中,hotspot/gc 代碼實現方面,引入一個乾淨的 GC 接口,改進不一樣 GC 源代碼的隔離性,多個 GC 之間共享的實現細節代碼應該存在於輔助類中。統一垃圾回收接口的主要緣由是:讓垃圾回收器(GC)這部分代碼更加整潔,便於新人上手開發,便於後續排查相關問題。

Java11

Java11 於 2018 年 9 月 25 日正式發佈,這是很重要的一個版本!Java 11 和 2017 年 9 月份發佈的 Java 9 以及 2018 年 3 月份發佈的 Java 10 相比,其最大的區別就是:在長期支持(Long-Term-Support)方面,Oracle 表示會對 Java 11 提供大力支持,這一支持將會持續至 2026 年 9 月。這是據 Java 8 之後支持的首個長期版本。

字符串增強

Java 11 增長了一系列的字符串處理方法,如如下所示。

Guide 哥:說白點就是多了層封裝,JDK 開發組的人沒少看市面上常見的工具類框架啊!

//判斷字符串是否爲空
" ".isBlank();//true
//去除字符串首尾空格
" Java ".strip();// "Java" 
//去除字符串首部空格
" Java ".stripLeading();   // "Java "  
//去除字符串尾部空格
" Java ".stripTrailing();  // " Java"  
//重複字符串多少次
"Java".repeat(3);             // "JavaJavaJava"  

//返回由行終止符分隔的字符串集合。
"A\nB\nC".lines().count();    // 3 
"A\nB\nC".lines().collect(Collectors.toList()); 
複製代碼

ZGC:可伸縮低延遲垃圾收集器

ZGC 即 Z Garbage Collector,是一個可伸縮的、低延遲的垃圾收集器。

ZGC 主要爲了知足以下目標進行設計:

  • GC 停頓時間不超過 10ms
  • 即能處理幾百 MB 的小堆,也能處理幾個 TB 的大堆
  • 應用吞吐能力不會降低超過 15%(與 G1 回收算法相比)
  • 方便在此基礎上引入新的 GC 特性和利用 colord
  • 針以及 Load barriers 優化奠基基礎
  • 當前只支持 Linux/x64 位平臺

ZGC 目前 處在實驗階段,只支持 Linux/x64 平臺

標準 HTTP Client 升級

Java 11 對 Java 9 中引入並在 Java 10 中進行了更新的 Http Client API 進行了標準化,在前兩個版本中進行孵化的同時,Http Client 幾乎被徹底重寫,而且如今徹底支持異步非阻塞。

而且,Java11 中,Http Client 的包名由 jdk.incubator.http 改成java.net.http,該 API 經過 CompleteableFuture 提供非阻塞請求和響應語義。

使用起來也很簡單,以下:

var request = HttpRequest.newBuilder()  

    .uri(URI.create("https://javastack.cn"))  

    .GET()  

    .build();  

var client = HttpClient.newHttpClient();  

// 同步  

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());  

System.out.println(response.body());  

// 異步  

client.sendAsync(request, HttpResponse.BodyHandlers.ofString())  

    .thenApply(HttpResponse::body)  

    .thenAccept(System.out::println); 


複製代碼

簡化啓動單個源代碼文件的方法

  • 加強了 Java 啓動器,使其可以運行單一文件的 Java 源代碼。此功能容許使用 Java 解釋器直接執行 Java 源代碼。源代碼在內存中編譯,而後由解釋器執行。惟一的約束在於全部相關的類必須定義在同一個 Java 文件中
  • 對於 Java 初學者並但願嘗試簡單程序的人特別有用,而且能和 jshell 一塊兒使用
  • 必定能程度上加強了使用 Java 來寫腳本程序的能力

用於 Lambda 參數的局部變量語法

  • 從 Java 10 開始,便引入了局部變量類型推斷這一關鍵特性。類型推斷容許使用關鍵字 var 做爲局部變量的類型而不是實際類型,編譯器根據分配給變量的值推斷出類型
  • Java 10 中對 var 關鍵字存在幾個限制
    • 只能用於局部變量上
    • 聲明時必須初始化
    • 不能用做方法參數
    • 不能在 Lambda 表達式中使用
  • Java11 開始容許開發者在 Lambda 表達式中使用 var 進行參數聲明

其餘特性

  • 新的垃圾回收器 Epsilon,一個徹底消極的 GC 實現,分配有限的內存資源,最大限度的下降內存佔用和內存吞吐延遲時間
  • 低開銷的 Heap Profiling:Java 11 中提供一種低開銷的 Java 堆分配採樣方法,可以獲得堆分配的 Java 對象信息,而且可以經過 JVMTI 訪問堆信息
  • TLS1.3 協議:Java 11 中包含了傳輸層安全性(TLS)1.3 規範(RFC 8446)的實現,替換了以前版本中包含的 TLS,包括 TLS 1.2,同時還改進了其餘 TLS 功能,例如 OCSP 裝訂擴展(RFC 6066,RFC 6961),以及會話散列和擴展主密鑰擴展(RFC 7627),在安全性和性能方面也作了不少提高
  • 飛行記錄器:飛行記錄器以前是商業版 JDK 的一項分析工具,但在 Java 11 中,其代碼被包含到公開代碼庫中,這樣全部人都能使用該功能了

Java12

加強 Switch

  • 傳統的 switch 語法存在容易漏寫 break 的問題,並且從代碼整潔性層面來看,多個 break 本質也是一種重複

  • Java12 提供了 swtich 表達式,使用相似 lambda 語法條件匹配成功後的執行塊,不須要多寫 break

  • 做爲預覽特性加入,須要在javac編譯和java運行時增長參數--enable-preview

    switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
        case TUESDAY                -> System.out.println(7);
        case THURSDAY, SATURDAY     -> System.out.println(8);
        case WEDNESDAY              -> System.out.println(9);
    }
    複製代碼

數字格式化工具類

  • NumberFormat 新增了對複雜的數字進行格式化的支持

    NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
    String result = fmt.format(1000);
     System.out.println(result); // 輸出爲 1K,計算工資是多少K更方便了。。。
    複製代碼

Shenandoah GC

  • Redhat 主導開發的 Pauseless GC 實現,主要目標是 99.9% 的暫停小於 10ms,暫停與堆大小無關等
  • 和 Java11 開源的 ZGC 相比(須要升級到 JDK11 才能使用),Shenandoah GC 有穩定的 JDK8u 版本,在 Java8 佔據主要市場份額的今天有更大的可落地性

G1 收集器提高

  • Java12 爲默認的垃圾收集器 G1 帶來了兩項更新:
    • 可停止的混合收集集合:JEP344 的實現,爲了達到用戶提供的停頓時間目標,JEP 344 經過把要被回收的區域集(混合收集集合)拆分爲強制和可選部分,使 G1 垃圾回收器能停止垃圾回收過程。 G1 能夠停止可選部分的回收以達到停頓時間目標
    • 及時返回未使用的已分配內存:JEP346 的實現,加強 G1 GC,以便在空閒時自動將 Java 堆內存返回給操做系統

Java13

引入 yield 關鍵字到 Switch 中

  • Switch 表達式中就多了一個關鍵字用於跳出 Switch 塊的關鍵字 yield,主要用於返回一個值

  • yieldreturn 的區別在於:return 會直接跳出當前循環或者方法,而 yield 只會跳出當前 Switch 塊,同時在使用 yield 時,須要有 default 條件

     private static String descLanguage(String name) {
            return switch (name) {
                case "Java": yield "object-oriented, platform independent and secured";
                case "Ruby": yield "a programmer's best friend";
                default: yield name +" is a good language";
            };
     }
    複製代碼

文本塊

  • 解決 Java 定義多行字符串時只能經過換行轉義或者換行鏈接符來變通支持的問題,引入三重雙引號來定義多行文本

  • 兩個"""中間的任何內容都會被解釋爲字符串的一部分,包括換行符

    String json ="{\n" +
                  "   \"name\":\"mkyong\",\n" +
                  "   \"age\":38\n" +
                  "}\n";   // 未支持文本塊以前
    複製代碼

     String json = """
                    {
                        "
    name":"mkyong",
                        "
    age":38
                    }
                    "
    "";
    複製代碼

加強 ZGC 釋放未使用內存

  • 在 Java 11 中是實驗性的引入的 ZGC 在實際的使用中存在未能主動將未使用的內存釋放給操做系統的問題
  • ZGC 堆由一組稱爲 ZPages 的堆區域組成。在 GC 週期中清空 ZPages 區域時,它們將被釋放並返回到頁面緩存 ZPageCache 中,此緩存中的 ZPages 按最近最少使用(LRU)的順序,並按照大小進行組織
  • 在 Java 13 中,ZGC 將向操做系統返回被標識爲長時間未使用的頁面,這樣它們將能夠被其餘進程重用

SocketAPI 重構

  • Java 13 爲 Socket API 帶來了新的底層實現方法,而且在 Java 13 中是默認使用新的 Socket 實現,使其易於發現並在排除問題同時增長可維護性

動態應用程序類-數據共享

  • Java 13 中對 Java 10 中引入的 應用程序類數據共享進行了進一步的簡化、改進和擴展,即: 容許在 Java 應用程序執行結束時動態進行類歸檔,具體可以被歸檔的類包括:全部已被加載,但不屬於默認基層 CDS 的應用程序類和引用類庫中的類

Java14

record 關鍵字

  • 簡化數據類的定義方式,使用 record 代替 class 定義的類,只須要聲明屬性,就能夠在得到屬性的訪問方法,以及 toString,hashCode,equals 方法

  • 相似於使用 Class 定義類,同時使用了 lomobok 插件,並打上了@Getter,@ToString,@EqualsAndHashCode註解

  • 做爲預覽特性引入

    /**
     * 這個類具備兩個特徵
     * 1. 全部成員屬性都是final
     * 2. 所有方法由構造方法,和兩個成員屬性訪問器組成(共三個)
     * 那麼這種類就很適合使用record來聲明
     */

    final class Rectangle implements Shape {
        final double length;
        final double width;

        public Rectangle(double length, double width) {
            this.length = length;
            this.width = width;
        }

        double length() return length; }
        double width() return width; }
    }
    /**
     * 1. 使用record聲明的類會自動擁有上面類中的三個方法
     * 2. 在這基礎上還附贈了equals(),hashCode()方法以及toString()方法
     * 3. toString方法中包括全部成員屬性的字符串表示形式及其名稱
     */

    record Rectangle(float length, float width) { }
    複製代碼

空指針異常精準提示

  • 經過 JVM 參數中添加-XX:+ShowCodeDetailsInExceptionMessages,能夠在空指針異常中獲取更爲詳細的調用信息,更快的定位和解決問題

    a.b.c.i = 99// 假設這段代碼會發生空指針
    複製代碼
    Exception in thread "main" java.lang.NullPointerException:
            Cannot read field 'c' because 'a.b' is null.
        at Prog.main(Prog.java:5// 增長參數後提示的異常中很明確的告知了哪裏爲空致使
    複製代碼

switch 的加強終於轉正

  • JDK12 引入的 switch(預覽特性)在 JDK14 變爲正式版本,不須要增長參數來啓用,直接在 JDK14 中就能使用
  • 主要是用 ->來替代之前的 :+ break;另外就是提供了 yield 來在 block 中返回值

Before Java 14

switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
複製代碼

Java 14 enhancements

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
複製代碼

instanceof 加強

  • instanceof 主要在類型強轉前探測對象的具體類型,而後執行具體的強轉

  • 新版的 instanceof 能夠在判斷的是否屬於具體的類型同時完成轉換

Object obj = "我是字符串";
if(obj instanceof String str){
 System.out.println(str);
}
複製代碼

其餘特性

  • 從 Java11 引入的 ZGC 做爲繼 G1 事後的下一代 GC 算法,從支持 Linux 平臺到 Java14 開始支持 MacOS 和 Window(我的感受是終於能夠在平常開發工具中先體驗下 ZGC 的效果了,雖然其實 G1 也夠用)
  • 移除了 CMS 垃圾收集器(功成而退)
  • 新增了 jpackage 工具,標配將應用打成 jar 包外,還支持不一樣平臺的特性包,好比 linux 下的 debrpm,window 平臺下的 msiexe

總結

關於預覽特性

  • 先貼一段 oracle 官網原文: This is a preview feature, which is a feature whose design, specification, and implementation are complete, but is not permanent, which means that the feature may exist in a different form or not at all in future JDK releases. To compile and run code that contains preview features, you must specify additional command-line options.
  • 這是一個預覽功能,該功能的設計,規格和實現是完整的,但不是永久性的,這意味着該功能可能以其餘形式存在或在未來的 JDK 版本中根本不存在。 要編譯和運行包含預覽功能的代碼,必須指定其餘命令行選項。
  • 就以 switch的加強爲例子,從 Java12 中推出,到 Java13 中將繼續加強,直到 Java14 才正式轉正進入 JDK 能夠放心使用,不用考慮後續 JDK 版本對其的改動或修改
  • 一方面能夠看出 JDK 做爲標準平臺在增長新特性的嚴謹態度,另外一方面我的認爲是對於預覽特性應該採起審慎使用的態度。特性的設計和實現容易,可是其實際價值依然須要在使用中去驗證

JVM 虛擬機優化

  • 每次 Java 版本的發佈都伴隨着對 JVM 虛擬機的優化,包括對現有垃圾回收算法的改進,引入新的垃圾回收算法,移除老舊的再也不適用於今天的垃圾回收算法等
  • 總體優化的方向是 高效,低時延的垃圾回收表現
  • 對於平常的應用開發者可能比較關注新的語法特性,可是從一個公司角度來講,在考慮是否升級 Java 平臺時更加考慮的是 JVM 運行時的提高

參考信息

本文使用 mdnice 排版

相關文章
相關標籤/搜索