作者 | 未讀代碼,CSDN 博主
封圖 | CSDN 下載自 VCG
出品 | CSDN 博客
自從 Java 9 開始,Oracle 調整了 Java 版本的發布策略,不再是之前的 N 年一個大版本,取而代之的是 6 個月一個小版本,三年一個大版本,這樣可以讓 Java 的最新改變迅速上線,而小版本的維護周期縮短到下個版本發布之前,大版本的維護周期則是 3 年之久。10 就是這麼一個小版本,因為 Java 的後續版本基本都會包含之前新特性,所以還是把 Java 10 帶來的改變單獨寫一寫。
JEP 322 - 基於時間的版本號
就像上面說的,Java 調整了發布策略,為了適應這種發布節奏,隨之改變的還有 Java 版本號的記錄方式。
版本號的新模式是:$FEATURE.$INTERIM.$UPDATE.$PATCH
$FEATURE :基於發布版本,如 Java 10 的 10 。$INTERIM :問題修復和功能增強時 + 1,默認是 0 。$UPDATE :在進行兼容更新,修復新功能安全問題時 +1。$PATCH :特殊問題修復時 +1。查看自己的 Java 10 版本。
$ java -versionjava version "10.0.1"2018-04-17Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)
JEP 286 - 局部類型推斷
JEP 286 提案讓 Java 增加了局部類型推斷(Local-Variable Type Inference)功能,這讓 Java 可以像 JS 裡的 var 或者其他語言的 auto 一樣可以自動推斷數據類型。這其實只是一個新的語法糖,底層並沒有變化,在編譯時就已經把 var 轉化成具體的數據類型了,但是這樣可以減少代碼的編寫。
你可以像下面這樣使用 var 語法。
var hashMap = new HashMap<String, String>();hashMap.put("wechat","wn8398");var string = "hello java 10";var stream = Stream.of(1, 2, 3, 4);var list = new ArrayList<String>();
如果你反編譯編譯後的這段代碼,你會發現還是熟悉的代碼片段。
HashMap<String, String> hashMap = new HashMap();hashMap.put("wechat", "wn8398");Stringstring = "hello java 10";Stream<Integer> stream = Stream.of(1, 2, 3, 4);ArrayList<String> list = new ArrayList();
var 看似好用,其實也有很多限制,官方介紹了 var 只能用於下面的幾種情況。
僅限帶有初始化的程序的局部變量。for 循環或者增強for 循環中。for循環中的聲明。下面演示三種使用情況。
publicstaticvoidtestVar() {// 情況1,沒有初始化會報錯// var list;var list = List.of(1, 2, 3, 4);// 情況2for (var integer : list) { System.out.println(integer); }// 情況3for (var i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }}
儘管對 var 的使用場景增加了很多限制,但在實際使用時你還是要注意,就像下面的代碼,你可能一眼並不能看出 result 的數據類型。
var query = "xxx";var result = dbUtil.executeQuery(query);
JEP 317 - 基於 Java 的 JIT 編譯器(實驗性)
這個功能讓基於 Java 開發的 JIT 編譯器 Graal 結合 Java 10 用在 Linux / x64 平臺上,這是一個實驗性的 JIT 編譯器,有人說這也是 Java 10 中最具有未來感的引入。Graal 其實在 Java 9 中就已經引入了,它帶來了 Java 中的 AOT (Ahead Of Time)編譯,還支持多種語言,如 Js、Python、Ruby、R、以及其他基於 JVM (如 Java、Kotlin)的和基於 LLVM (如 C、C++)的語言。
想切換到 Graal 可以使用下面的 jvm 參數。
-XX:+UnlockExperimentalVMOptions-XX:+UseJVMCICompiler
這裡面有一點我覺得很有意思,看這個圖。
這就很有意思了,Graal 是 Java 語言編寫的,用 Java 編寫的編譯器,然後用來將 Java 字節碼編譯機器代碼。
JEP 310 - 類數據共享
JVM 啟動時有一步是需要在內存中加載類,而如果有多個 jar,加載第一個 jar 的速度是最慢的。這就延長了程序的啟動時間,為了減少這個時間,Java 10 引入了應用程式類數據共享(CDS)機制,它可以把你想共享的類共享在程序之間,使不同的 Java 進程之間共享這個類來減少這個類佔用的空間以及加載速度。
JEP 307 - G1 並行全GC
早在 Java 9 時就已經引入了 G1 垃圾收集器,G1 的優點很多。而在 Java 10 中還是做了小小調整,當 G1 的並發收集線程不能快速的完成全 GC 時,就會自動切換到並行收集,這可以減少在最壞情況下的 GC 速度。
JEP 314 - Unicode 語言標籤擴展
這個提案讓 JDK 實現了最新的 LDML 規範中指定的更多的擴展。
主要增加了下面幾個擴展方法。
java.time.temporal.WeekFields::ofjava.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}java.util.Currency::getInstancejava.util.Locale::getDisplayNamejava.util.spi.LocaleNameProviderjava.text.DateFormat::get*Instancejava.text.DateFormatSymbols::getInstancejava.text.DecimalFormatSymbols::getInstancejava.text.NumberFormat::get*Instancejava.time.format.DateTimeFormatter::localizedByjava.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePatternjava.time.format.DecimalStyle::of
嘗試一下。
Currency chinaCurrency = Currency.getInstance(Locale.CHINA);Currency usCurrency = Currency.getInstance(Locale.US);System.out.println("本地貨幣:" + chinaCurrency);System.out.println("US.貨幣:" + usCurrency);String displayName = Locale.getDefault().getDisplayName();String displayLanguage = Locale.getDefault().getDisplayLanguage();String displayCountry = Locale.getDefault().getDisplayCountry();System.out.println("本地名稱:" + displayName);System.out.println("本地語言:" + displayLanguage);System.out.println("本地國家:" + displayCountry);int firstDayOfWeek = Calendar.getInstance().getFirstDayOfWeek();System.out.println("本地每周第一天:" + firstDayOfWeek);
輸出結果。
本地貨幣:CNYUS.貨幣:USD本地名稱:中文 (中國)本地語言:中文本地國家:中國本地每周第一天:1
API 更新
Java 10 刪除了部分 API,也增加了一些實用方法。比如可以通過 Collection.copyOf 複製得到一個不可改變集合,即使原來的集合元素發生了變化也不會有影響。
varlist = new ArrayList<String>();list.add("wechat");list.add("wn8398");List<String> copyList = List.copyOf(list);list.add("test");System.out.println(copyList);// result// [wechat, wn8398]
也為 Optional 增加了一個新的方法 orElseThrow。調用這個方法也可以獲取到 optional 中的 value , 但是如果 value 為 null ,就會拋出異常。
另外在 Stream 最後收集數據的時候,Collectors 可以直接指定收集的集合為不可變集合,像下面這樣。
list.stream().collect(Collectors.toUnmodifiableList());list.stream().collect(Collectors.toUnmodifiableSet());
其他更新
Java 10 的更新內容不止這些,上面只是列舉了常用的以及比較有意思的新特性。還有部分更新如:
JEP 312:Thread-Local Handshakes,JVM 內部功能,可以提高 JVM 性能。JEP 313:刪除了 javah 工具,說是刪除,其實功能已經包含在 Java 8 中的 javac 裡。JEP 316:讓 JVM 可以在備用的存儲設備(如 NV-DIMM)上分配堆內存,而不用更改程序代碼。JEP 319:在JDK中提供一組默認的根證書頒發機構(CA)證書。文章案例都已經上傳到 Github:niumoo/jdk-feature
本文為 CSDN 博主「未讀代碼」原創文章,CSDN 官方經授權發布。
原文地址:https://blog.csdn.net/u013735734/article/details/104510202
【End】
在全民抗疫的特殊時期下,在人員複雜、流動量大地方的出入口處都設置了無接觸式無感紅外人體測溫系統。
在這次疫情防控中,無感人體測溫系統發揮了怎樣的作用?高精準的無感人體測溫系統的核心技術武器是什麼?對於開發者們來說,大家應該了解哪些技術?
今晚7點《多場景疫情防控:解讀雲邊端聯動下的全棧 AI 技術應用》