Java10新特性解讀

Java10是Java版本23年歷史上最快的版本。Java因其緩慢的增長和進化而受到批評,但Java10打破瞭這一概念。Java10是一個具有許多未來變化的版本,其范圍和影響可能並不明顯,但卻很牽強。

在本文中,我們將討論Java10發行版中添加的各種特性。在此之前,讓我們回顧一下java發佈模型中引入的一些更改。

長期支持模式

從2017年開始,Oracle&Java社區宣佈將向為期6個月的Java新節奏轉變。它轉向瞭oracle javase產品的長期支持(LTS)模型。

LTS版本的產品將提供甲骨文卓越和持續的支持,並將每3年瞄準一次。

每個Java發行版都是以一個或兩個主要特性為模型的,這些特性驅動發行版。任何障礙都會推遲發佈和推遲上市。Jigsaw項目是Java9的一個主要特性,它將發佈日期推遲瞭幾次,發佈時間推遲瞭1.5年以上。6個月的cadence發佈將遵循發佈序列。放行列車每6個月有一個時間表。使切口上車的特征;否則它們等待下一列預定的火車。

Oracle JDK與Open JDK之比較

為瞭對開發人員更加友好,Oracle&Java社區現在將OpenJDK作為主要JDK來推廣。這與早些時候相比是一個很大的解脫,當時JDK是適當的,並由Oracle授權,Oracle對重新分發有各種限制。不過,Oracle將繼續生產JDK,但隻針對長期支持版本。這是朝著更加雲和容器友好的方向發展,因為開放的JDK庫可以作為容器的一部分分發。

openjdk將每6個月發佈一次,而Oracle JDK將每3年發佈一次(LTS版本)。

將采用哪些JDK?

大型組織需要時間在不同的版本之間移動;他們會緊緊抓住版本直到他們能做到為止。行業對Java6的采用超過瞭Java7,然後行業逐漸轉向Java8。在我看來,LTS版本將是最受企業青睞的。然而,究竟是oraclejdk的LTS版本還是openjdk還不清楚,部分原因是雲計算領域正在進行大量工作。

Java9和Java10是非LTS版本。定於2018年9月發佈的Java11將是LTS版本。

Java10功能

讓我們來看看Java10中可用的特性。

基於時間的版本控制(JEP 322)

隨著基於時間的發佈周期的采用,Oracle改變瞭javase平臺和JDK的版本字符串方案,以及相關的版本控制信息,用於當前和未來基於時間的發佈模型。

版本號的新模式是:

$FEATURE.$INTERIM.$UPDATE.$PATCH

$FEATURE:counter將每6個月遞增一次,並且將基於功能發佈版本,例如:JDK 10、JDK 11。

$INTERIM: counter 對於包含兼容的錯誤修復和增強但沒有不兼容更改的非功能版本,計數器將增加。通常,這將是零,因為六個月內不會有臨時發佈。這是為瞭將來對發佈模型進行修訂而保留的。

$UPDATE:counter對於修復新特性中的安全問題、退化和bug的兼容更新版本將增加。此功能發佈後一個月更新,以後每3個月更新一次。2018年4月的版本是JDK10.0.1,7月的版本是JDK10.0.2,以此類推

$PATCH:counter將在緊急版本中增加,以修復關鍵問題。

添加瞭新的API以編程方式獲取這些計數器值。讓我們看看;

Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();

現在,讓我們看看返回版本信息的Java launcher:

$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

版本號格式是“10”,因為除瞭0之外沒有其他計數器。添加發佈日期。18.3可以理解為2018年和第3個月,版本10+46是版本10的第46個版本。對於JDK10.0.1的假設構建93,構建將是10.0.1+93

局部變量類型推斷(JEP 286)

局部變量類型推斷是Java10中為開發人員提供的最大的新特性。它將類型推斷添加到帶有初始值設定項的局部變量聲明中。局部類型推斷隻能在以下情況下使用:

  • 僅限於具有初始值設定項的局部變量
  • 增強for循環的索引
  • 在for循環中聲明的本地

我們來看看它的用法:

var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList<String>
// Index of Enhanced For Loop
for (var number : numbers) {
	System.out.println(number);
}
// Local variable declared in a loop
for (var i = 0; i < numbers.size(); i++) {
	System.out.println(numbers.get(i));
}

實驗性基於Java的JIT編譯器(JEP 317)

這個特性使基於Java的JIT編譯器Graal能夠在Linux/x64平臺上作為一個實驗性的JIT編譯器使用。到目前為止,這是Java10特性列表中最具未來感的內容。

Graal是在java9中引入的。它是我們已經習慣的JIT編譯器的替代品。它是JVM的一個插件,這意味著JIT編譯器沒有綁定到JVM,它可以動態地插入JVMCI兼容的任何其他插件(Java級JVM編譯器接口)。它還帶來瞭java世界中的提前編譯(AOT)。它還支持多語言翻譯。

“一個用Java編寫的基於Java的實時編譯器,用於將Java字節碼轉換為機器碼。”這讓人困惑嗎?如果JVM是用Java編寫的,那麼您不需要JVM來運行JVM嗎?JVM可以通過AOT編譯,然後JIT編譯器可以在jvmit中使用,通過實時代碼優化來提高性能。

Graal是用Java從頭開始的對JIT編譯器的完全重寫。以前的JIT編譯器是用c++編寫的。它被認為是任何編程語言進化的最後階段。

您可以使用以下jvm參數切換到Graal:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

應用程序級數據共享(JEP 310)

此功能有助於改善啟動占用空間,擴展現有的類數據共享(“CDS”)功能,以允許將應用程序類放置在共享存檔中。

JVM在啟動時執行一些初步步驟,其中一個步驟是在內存中加載類。如果有幾個jar有多個類,那麼第一個請求中的延遲就很明顯瞭。這成為無服務器體系結構的一個問題,其中引導時間至關重要。為瞭縮短應用程序啟動時間,可以使用應用程序類數據共享。其思想是通過在不同的Java進程之間共享公共類元數據來減少占用空間。可通過以下3個步驟實現:

確定要存檔的類:使用java啟動器創建要存檔的文件列表,這可以通過以下參數實現:

$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld

創建AppCDS存檔:使用java launcher創建要用於應用程序cd的文件列表的存檔,這可以通過以下參數實現:

$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar

使用AppCDS存檔:使用帶有以下參數的Java啟動器來使用應用程序cd。

$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld

G1並行Full GC(JEP 307)

G1垃圾收集器在jdk9中是默認的。G1垃圾收集器避免瞭任何完全的垃圾收集,但是當用於收集的並發線程不能足夠快地恢復內存時,用戶的體驗就會受到影響。

此更改通過使完全GC並行來改善G1最壞情況下的延遲。G1收集器的mark-sweep compact算法作為此更改的一部分被並行化,當用於收集的並發線程不能足夠快地恢復內存時,它將被觸發。

垃圾收集器接口(JEP 304)

這個JEP是未來的變化。它通過引入一個通用的垃圾收集器接口來改進不同垃圾收集器的代碼隔離。

此更改為內部GC代碼提供瞭更好的模塊化。它將有助於將來添加新的GC而不改變現有的代碼基,也有助於刪除或管理以前的GC。

附加Unicode語言標記擴展(JEP 314)

此功能增強瞭java.util.Locale語言環境以及相關的API來實現BCP 47語言標記的額外Unicode擴展。從JavaSE9開始,支持的BCP47U語言標記擴展是“ca”和“nu”。此JEP將添加對以下附加擴展的支持:

  • cu(貨幣類型)
  • fw(每周第一天)
  • rg(區域覆蓋)
  • tz(時區)

為瞭支持這些附加擴展,對各種api進行瞭更改,以提供基於U或附加擴展的信息。

java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider

根證書(JEP 319)

為瞭推廣OpenJDK並使其對社區用戶更具吸引力,此功能在JDK中提供瞭一組默認的根證書頒發機構(CA)證書。這也意味著Oracle和openjdk二進制文件在功能上是相同的。

關鍵的安全組件(如TLS)將在OpenJDK構建中默認工作。

Thread-Local 線程本地握手(JEP 312)

這是一個用於提高性能的內部JVM特性。

握手操作是在每個JavaThread處於safepoint狀態時對其執行的回調。回調要麼由線程本身執行,要麼由VM線程執行,同時保持線程處於阻塞狀態。

此功能提供瞭一種在線程上執行回調而不執行全局VM safepoint的方法。使停止單個線程,而不僅僅是停止所有線程或不停止任何線程既可能又便宜。

替代內存設備上的堆分配(JEP 316)

應用程序已經變得內存匱乏,雲本地應用程序、內存數據庫、流式應用程序都在增加。為瞭滿足這些服務,有各種可用的內存體系結構。此功能增強瞭HotSpot VM在用戶指定的備用內存設備(如NV-DIMM)上分配Java對象堆的能力。

此JEP針對具有與DRAM相同的語義(包括原子操作的語義)的替代內存設備,因此,可以在不更改現有應用程序代碼的情況下代替DRAM用於對象堆。

刪除Native-Header生成工具Javah(Jep313)

這是一個從JDK中刪除javah工具的內務管理更改。javac中添加的工具功能是jdk8的一部分,它提供瞭在編譯時編寫Native-Header文件的能力,從而使javah變得無用。

將JDK林整合到單個存儲庫中(JEP 296)

多年來,在JDK代碼庫中有各種Mercurial存儲庫。不同的存儲庫確實提供瞭一些優勢,但它們也有不同的操作缺點。作為此更改的一部分,JDK的許多存儲庫被合並到一個存儲庫中,以簡化開發。

API更改

Java10已經添加和刪除瞭API(是的,它不是一個拼寫錯誤)。

Java9引入瞭增強的棄用,其中某些API被標記為在將來的版本中刪除。

添加瞭API:Java10中添加瞭73個新API。

讓我們看一些補充:

ListMapSet接口是通過靜態copyOf(Collection)方法添加的。它返回一個不可修改的列表、映射或集合,其中包含所提供的條目。對於列表,如果給定的列表隨後被修改,則返回的列表將不會反映這些修改。

Optional&它的原語變體獲取一個方法orelsetrow()。這與get()完全相同,但是javadoc聲明它是get()的首選替代方法

Collectors類獲取用於收集不可修改集合(SetListMap)的各種方法

List<String> actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// New API added - Creates an UnModifiable List from a List.
List<String> copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Will generate an
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
		
String str = "";
Optional<String> name = Optional.ofNullable(str);
// New API added - is preferred option then get() method
name.orElseThrow(); // same as name.get() 

// New API added - Collectors.toUnmodifiableList
List<String> collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Will generate an
// UnsupportedOperationException

以上就是Java10新特性總結的詳細內容,更多關於Java10新特性的資料請關註WalkonNet其它相關文章!

推薦閱讀: