Java14 上個月發布了,官方解讀:https://openjdk.java.net/projects/jdk/14/
先中文翻譯一下:
下面驗證一下Java14"真香定律"~
一 、准備工作
安裝JDK14;
IDEA最新版的(2020.1版以后的,舊版可能不支持,其他編輯器沒試過)
二 、新特性
①Pattern Matching for instanceof (Preview) 模式匹配
Object obj = "java14"; //測試一把 if (obj instanceof String sss && sss.length() > 5) { System.out.println(sss.contains("b")); System.out.println("這是字符串!sss" + sss); } else { System.out.println("其他~"); }
在 instanceof 后面直接可以轉換類型, 不用再將Object轉成String,言簡意賅。
②Packaging Tool (Incubator) 打包工具
這里主要是提供一種像安裝程序的方式類似的安裝體驗,針對之前可運行的 .jar 文件,提供一種面向不同 os 的打包格式的工具,這個工具可以支持 Windows 下的 msi 和 exe 格式、 linux 下的 dep 和 rpm 格式以及 Mac 下的 pkg 和 dmg 格式,這里除了打包之后有一個通用的系統的安裝體驗之外,還能將一些 main 函數啟動的初始入參固化到打包之后的文件中。
整體打包的命令會根據是否是做了模塊化有所區別,分別是:
jpackage --name myapp --input lib --main-jar main.jar
以及
jpackage --name myapp --module-path lib -m myapp
可以通過 --type 來指定打包之后的格式,比如上述命令后面加入 --type dmg ,就是打包出 dmg 格式的安裝包;
這個工具的動機主要是之前直接運行jar文件的方式需要使用方關心三個問題:
1、lib 的路徑;
2、是否有顯性的 main 函數指定和聲明;
3、main 函數的入參;
這個工具可以簡化 jar 文件使用的門檻;;(---摘抄於大佬原話)
③ NUMA-Aware Memory Allocation for G1 針對G1的NUMA感知內存分配
這個點是基於 G1 垃圾回收器的,主要是針對年輕代的對象內存分配做了一個優化,提高的是 CPU 計算過程中的內存訪問速度;
NUMA 是 non-unified memory access 的縮寫,主要是指在當前的物理機中,比較普遍是多核的,這樣每個核對於每一塊或者某一區域的內存訪問速度會隨着核和物理內存所在的位置的遠近而有不同的時延差異(在同一塊物理 scoket 上的 cpu 對於不同距離的內存訪問基本時延相同),這個就是這個優化的一個大前提;
然后在 Java 中,堆內存分配一般發生在線程運行的時候,new 了一個新對象,然后該線程會觸發 G1 去 allocate 一塊內存出來,用來存放新的對象,在 G1 中,其實就是一塊region(大對象除外,大對象需要多個 region ,但是不在這個優化的范疇中),那其實就在這個 allocation 分配新內存的過程中,優先在當前線程所綁定的同個 NUMA node 內存,因為是基於同一個線程中創建的對象大部分是短存活並且高概率互相調用的,如果沒有足夠的可分配內存,就會觸發一次 YGC 。
這個點的優化,個人感覺性能優化可能比較有限;(---摘抄於大佬原話)
④JFR Event Streaming JFR事件流
JFR事件流 提供了一個API,用於持續使用來自流程內和流程外應用程序的JFR數據。
JFR是用於收集有關正在運行的Java應用程序的概要分析和診斷數據的工具。事件流建議記錄與非流情況相同的事件集,並且如果可能,開銷小於百分之一。事件流必須與基於磁盤和基於內存的非流記錄共存。
在這種情況下,HotSpot VM使用JFR發出500個以上的數據點,而其中的大多數數據僅可通過分析日志文件來使用,因此很容易激發這種提議。當前,用戶必須開始錄制,停止錄制,將內容轉儲到磁盤,然后解析錄制文件。這對於應用程序概要分析非常有效,但不適用於監視目的。監控使用情況的一個實例是顯示動態更新數據的儀表板。創建記錄會產生開銷,例如將數據從磁盤存儲庫復制到單獨的記錄文件。如果有一種方法可以在不創建新記錄文件的情況下從磁盤存儲庫中讀取正在記錄的數據,則可以避免很多開銷。
⑤Helpful NullPointerExceptions 有用的空指針
以前的空指針只會定位到一行(生產環境讓人抓狂),現在可以定位到具體的哪一個對象為null。
注意:調試時候需要加參數: -XX:+ShowCodeDetailsInExceptionMessages
⑥Switch Expressions Switch表達式
以前的switch里面,一個case后面接一個break;(考試題經常省略break來忽悠學僧) 。現在可以直接寫
⑦Records 記錄類
跟正常使用的javabean稍有區別,record標識后是一個final修飾的類,不能被繼承
有時候遇到一些簡單的數據載體,比如用到Person類,只有兩個屬性,age和name。
創建一個類后正常的做法(或者借助於lombock插件):
- toString()方法
- hashCode() and equals()方法
- Getter 方法
- 一個共有的構造函數
現在你可以直接用record啦(就這么一行);
record Person(int age, String name) { }
然后使用:
Person person1 = new Person(10,"tom"); System.out.println(person1.toString()); //Person[age=10, name=tom] System.out.println(person1.age()); //10 System.out.println(person1.name()); //tom
⑧Text Blocks (Second Preview) 文本塊
這個特性之前在 Java13 的時候出現過,preview,就是個偏實驗測試的特性,這次在 14 中,依舊是 preview ,主要是擴展了兩個 escape sequence ,分別是 “\” 和 “\s” , “\” 主要是用來明確標明換行的位置及之前的內容,主要是保留行末的空格,
如果拼接一個html的話,需要很多" " 和換行處理,格式看上去很丑~
String html = "<html>\n" + " <body>\n" + " <p>Hello, world</p>\n" + " </body>\n" + "</html>\n";
用文本塊之后,看上去比較直觀,也可以寫SQL語句塊。
String html = """ <html> <body> <p>Hello, world</p> </body> </html> """;
⑨ZGC on macOS & Windows
擴展 ZGC ,能夠在 macOS 和 Windows (版本有限制)上使用,主要是兼容這兩個系統和 linux 系統底層的內存映射機制的不同帶來的差異;
⑩其他
·棄用Solaris和SPARC端口
·刪除並發標記掃描(CMS)垃圾收集器
·棄用ParallelScavenge + SerialOld GC組合
·刪除Pack200工具和API
·外部存儲器訪問API(孵化器)
三、總結
雖然目前Java8使用的比較多,但是關注一下Java發展趨勢,看一下大佬們對Java未來的規划,我們從中可以受到一些啟發。
參考: https://mp.weixin.qq.com/s/1F3Dr4_jdGZd3eqdhvdQZA , http://www.situedu.com/news/uid/3445.html