1.1 JDK 各版本主要特性回顧
JDK Version 1.0
1996-01-23 Oak(橡樹)
- 初代版本,偉大的一個(gè)里程碑,但是是純解釋運(yùn)行,使用外掛JIT,性能比較差,運(yùn)行速度慢。
JDK Version 1.1
1997-02-19
- JDBC(
Java DataBase Connectivity
); - 支持內(nèi)部類;
- RMI(
Remote Method Invocation
) ; - 反射;
- Java Bean;
JDK Version 1.2
- 集合框架;
-
JIT(Just In Time)
編譯器; - 對(duì)打包的
Java
文件進(jìn)行數(shù)字簽名; - JFC(
Java Foundation Classes
), 包括Swing 1.0
, 拖放和Java2D
類庫(kù); - Java插件;
-
JDBC
中引入可滾動(dòng)結(jié)果集,BLOB,CLOB
,批量更新和用戶自定義類型; -
Applet
中添加聲音支持. - 同時(shí),Sun發(fā)布了
JSP/Servlet
、EJB規(guī)范,以及將Java分成了J2EE
、J2SE
和J2ME
。 這表明了 Java開始向企業(yè)、桌面 - 應(yīng)用和移動(dòng)設(shè)備應(yīng)用3大領(lǐng)域挺進(jìn)。
JDK Version 1.3
2000-05-08 Kestrel
(紅隼)
-
Java Sound API
; -
jar
文件索引; - 對(duì)
Java
的各個(gè)方面都做了大量?jī)?yōu)化和增強(qiáng);
JDK Version 1.4
2004-02-06 Merlin
(隼)
- XML處理;
Java
打印服務(wù);Logging API
;Java Web Start
;JDBC 3.0 API
;- 斷言;
Preferences API
;- 鏈?zhǔn)疆惓L幚?
- 支持
IPV6
; - 支持正則表達(dá)式;
- 引入
Imgae I/O API
.
JAVA 5
2004-09-30 Tiger
(老虎)
- 泛型;
- 增強(qiáng)循環(huán),可以使用迭代方式;
- 自動(dòng)裝箱與自動(dòng)拆箱;
- 類型安全的枚舉;
- 可變參數(shù);
- 靜態(tài)引入;
- 元數(shù)據(jù)(注解);
-
Instrumentation
;
JAVA 6
2006-12-11 Mustang
(野馬)
- 支持腳本語言;
JDBC 4.0API
;Java Compiler API
;- 可插拔注解;
- 增加對(duì)
Native PKI
(Public Key Infrastructure
),Java GSS
(Generic Security Service
),Kerberos
和LDAP
(Lightweight Directory Access Protocol
)支持; - 繼承
Web Services;
JAVA 7
2011-07-28 Dolphin
(海豚)
-
switch
語句塊中允許以字符串作為分支條件; - 在創(chuàng)建泛型對(duì)象時(shí)應(yīng)用類型推斷;
- 在一個(gè)語句塊中捕獲多種異常;
- 支持動(dòng)態(tài)語言;
- 支持
try-with-resources
(在一個(gè)語句塊中捕獲多種異常); - 引入
Java NIO.2
開發(fā)包; - 數(shù)值類型可以用二進(jìn)制字符串表示,并且可以在字符串表示中添加下劃線;
鉆石型語法(在創(chuàng)建泛型對(duì)象時(shí)應(yīng)用類型推斷); -
null
值得自動(dòng)處理;
JAVA 8
2014-03-18
-
Lambda
表達(dá)式 ?Lambda
允許把函數(shù)作為一個(gè)方法的參數(shù)(函數(shù)作為參數(shù)傳遞進(jìn)方法中。 -
方法引用 ? 方法引用提供了非常有用的語法,可以直接引用已有Java類或?qū)ο螅▽?shí)例)的方法或構(gòu)造器。與
lambda
聯(lián)合使用,方法引用可以使語言的構(gòu)造更緊湊簡(jiǎn)潔,減少冗余代碼。 - 默認(rèn)方法 ? 默認(rèn)方法就是一個(gè)在接口里面有了一個(gè)實(shí)現(xiàn)的方法。
-
新工具 ? 新的編譯工具,如:
Nashorn
引擎 jjs、 類依賴分析器jdeps
。 -
Stream API
?新添加的Stream API
(java.util.stream
) 把真正的函數(shù)式編程風(fēng)格引入到Java中。 -
Date Time API
? 加強(qiáng)對(duì)日期與時(shí)間的處理。 -
Optional 類 ? Optional
-類已經(jīng)成為Java 8
類庫(kù)的一部分,用來解決空指針異常。 -
Nashorn, JavaScript
引擎 ? Java 8提供了一個(gè)新的Nashorn javascript
引擎,它允許我們?cè)贘VM上運(yùn)行特定的javascript
應(yīng)用。
JAVA 9
2017-09-22
-
模塊系統(tǒng):模塊是一個(gè)包的容器,
Java 9
最大的變化之一是引入了模塊系統(tǒng)(Jigsaw 項(xiàng)目)。 -
REPL (JShell)
:交互式編程環(huán)境。 -
HTTP 2
客戶端:HTTP/2
標(biāo)準(zhǔn)是HTTP
協(xié)議的最新版本,新的HTTPClient API
支持WebSocket
和HTTP2
流以及服務(wù)器推送特性。 -
改進(jìn)的
Javadoc
:Javadoc
現(xiàn)在支持在 API 文檔中的進(jìn)行搜索。另外,Javadoc
的輸出現(xiàn)在符合兼容 HTML5 標(biāo)準(zhǔn)。 -
多版本兼容 JAR 包:多版本兼容
JAR
功能能讓你創(chuàng)建僅在特定版本的 Java 環(huán)境中運(yùn)行庫(kù)程序時(shí)選擇使用的 class 版本。 -
集合工廠方法:
List,Set
和Map
接口中,新的靜態(tài)工廠方法可以創(chuàng)建這些集合的不可變實(shí)例。 -
私有接口方法:在接口中使用private私有方法。我們可以使用
private
訪問修飾符在接口中編寫私有方法。 -
進(jìn)程 API: 改進(jìn)的 API 來控制和管理操作系統(tǒng)進(jìn)程。引進(jìn)
java.lang.ProcessHandle
及其嵌套接口 Info 來讓開發(fā)者逃離時(shí)常因?yàn)橐@取一個(gè)本地進(jìn)程的 PID 而不得不使用本地代碼的窘境。 -
改進(jìn)的
Stream API
:改進(jìn)的Stream API
添加了一些便利的方法,使流處理更容易,并使用收集器編寫復(fù)雜的查詢。 -
改進(jìn)
try-with-resources
:如果你已經(jīng)有一個(gè)資源是 final 或等效于 final 變量,您可以在try-with-resources
語句中使用該變量,而無需在try-with-resources
語句中聲明一個(gè)新變量。 -
改進(jìn)的棄用注解
@Deprecated
:注解@Deprecated
可以標(biāo)記 Java API 狀態(tài),可以表示被標(biāo)記的 API 將會(huì)被移除,或者已經(jīng)破壞。 -
改進(jìn)鉆石操作符
(Diamond Operator)
:匿名類可以使用鉆石操作符(Diamond Operator)
。
改進(jìn)Optional
類:java.util.Optional
添加了很多新的有用方法,Optional
可以直接轉(zhuǎn)為stream
。 -
多分辨率圖像 API:定義多分辨率圖像API,開發(fā)者可以很容易的操作和展示不同分辨率的圖像了。
改進(jìn)的CompletableFuture API
:CompletableFuture
類的異步機(jī)制可以在ProcessHandle.onExit
方法退出時(shí)執(zhí)行操作。 -
輕量級(jí)的
JSON API
:內(nèi)置了一個(gè)輕量級(jí)的JSON API
-
響應(yīng)式流(
Reactive Streams
) API: Java 9中引入了新的響應(yīng)式流 API 來支持 Java 9 中的響應(yīng)式編程。
JAVA 10
2018-03-21
根據(jù)官網(wǎng)的公開資料,共有12個(gè)重要特性,如下:
-
JEP286,
var
局部變量類型推斷。 -
JEP296,將原來用
Mercurial
管理的眾多JDK
倉(cāng)庫(kù)代碼,合并到一個(gè)倉(cāng)庫(kù)中,簡(jiǎn)化開發(fā)和管理過程 - JEP304,統(tǒng)一的垃圾回收接口。
- JEP307,G1 垃圾回收器的并行完整垃圾回收,實(shí)現(xiàn)并行性來改善最壞情況下的延遲。
-
JEP310,應(yīng)用程序類數(shù)據(jù) (
AppCDS
) 共享,通過跨進(jìn)程共享通用類元數(shù)據(jù)來減少內(nèi)存占用空間,和減少啟動(dòng)時(shí)間。 -
JEP312,
ThreadLocal
握手交互。在不進(jìn)入到全局 JVM 安全點(diǎn) (Safepoint
) 的情況下,對(duì)線程執(zhí)行回調(diào)。優(yōu)化可以只停止單個(gè)線程,而不是停全部線程或一個(gè)都不停。 -
JEP313,移除
JDK
中附帶的javah
工具。可以使用javac -h
代替。 - JEP314,使用附加的 Unicode 語言標(biāo)記擴(kuò)展。
- JEP317,能將堆內(nèi)存占用分配給用戶指定的備用內(nèi)存設(shè)備。
-
JEP317,使用
Graal
基于 Java 的編譯器,可以預(yù)先把 Java 代碼編譯成本地代碼來提升效能。 -
JEP318,在
OpenJDK
中提供一組默認(rèn)的根證書頒發(fā)機(jī)構(gòu)證書。開源目前Oracle
提供的的Java SE
的根證書,這樣OpenJDK
對(duì)開發(fā)人員使用起來更方便。 -
JEP322,基于時(shí)間定義的發(fā)布版本,即上述提到的發(fā)布周期。版本號(hào)為
FEATURE.INTERIM.UPDATE.PATCH
,分j別是大版本,中間版本,升級(jí)包和補(bǔ)丁版本。
JAVA 11
2018-09-25
翻譯后的新特性有:
- 181:
Nest-Based
訪問控制 - 309:動(dòng)態(tài)類文件常量
- 315:改善
Aarch64 intrinsic
- 318:無操作垃圾收集器
- 320:消除Java EE和CORBA模塊
- 321:HTTP客戶端(標(biāo)準(zhǔn))
- 323:局部變量的語法λ參數(shù)
- 324:
Curve25519
和Curve448
關(guān)鍵協(xié)議 - 327:
Unicode 10
- 328:飛行記錄器
- 329:
ChaCha20
和Poly1305
加密算法 - 330:發(fā)射一列縱隊(duì)源代碼程序
- 331:低開銷堆分析
- 332:傳輸層安全性
(Transport Layer Security,TLS)1.3
- 333:動(dòng)作:一個(gè)可伸縮的低延遲垃圾收集器 (實(shí)驗(yàn))
- 335:反對(duì)
Nashorn JavaScript
引擎 - 336:反對(duì)
Pack200
工具和API
JAVA 12
2018-09-25
翻譯后的新特性有:
- 189:
Shenandoah: A Low-Pause-Time Garbage Collector (Experimental)
:新增一個(gè)名為Shenandoah
的垃圾回收器,它通過在 Java 線程運(yùn)行的同時(shí)進(jìn)行疏散 (evacuation
) 工作來減少停頓時(shí)間。 - 230:
Microbenchmark Suite
:新增一套微基準(zhǔn)測(cè)試,使開發(fā)者能夠基于現(xiàn)有的Java Microbenchmark
Harness(JMH)輕松測(cè)試 JDK 的性能,并創(chuàng)建新的基準(zhǔn)測(cè)試。 - 325:
Switch Expressions (Preview)
:對(duì) switch 語句進(jìn)行擴(kuò)展,使其可以用作語句或表達(dá)式,簡(jiǎn)化日常代碼。 - 334:
JVM Constants API
:引入一個(gè) API 來對(duì)關(guān)鍵類文件 (key class-file
) 和運(yùn)行時(shí)工件的名義描述(nominal descriptions
)進(jìn)行建模,特別是那些可從常量池加載的常量。 - 340:
One AArch64 Port, Not Two
:刪除與 arm64 端口相關(guān)的所有源碼,保留 32 位 ARM 移植和 64 位aarch64
移植。 - 341:
Default CDS Archives
:默認(rèn)生成類數(shù)據(jù)共享(CDS)存檔。 - 344:
Abortable Mixed Collections for G1
:當(dāng) G1 垃圾回收器的回收超過暫停目標(biāo),則能中止垃圾回收過程. - 346:
Promptly Return Unused Committed Memory from G1
:改進(jìn) G1 垃圾回收器,以便在空閑時(shí)自動(dòng)將Java
堆內(nèi)存返回給操作系統(tǒng)。
1.2 JDK 各版本支持周期
為了更快地迭代,Java的更新從傳統(tǒng)的以特性驅(qū)動(dòng)的發(fā)布周期,轉(zhuǎn)變?yōu)橐詴r(shí)間驅(qū)動(dòng)的(6 個(gè)月為周期)發(fā)布模式
每半年發(fā)布一個(gè)大版本,每個(gè)季度發(fā)布一個(gè)中間特性版本,并且承諾不會(huì)食言。通過這樣的方式,開發(fā)團(tuán)隊(duì)可以把
些關(guān)鍵特性盡早合并到 JDK 之中,以快速得到開發(fā)者反饋,按照官方的說法,新的發(fā)布周期會(huì)嚴(yán)格遵循時(shí)間點(diǎn),將于每年的3月份和9月份發(fā)布。所以 Java 11 的版本號(hào)是18.9(LTS,long term support)
。Oracle 直到2023年9月都會(huì)為 Java 11 提供技術(shù)支持,而補(bǔ)丁和安全警告等擴(kuò)展支持將持續(xù)到2026年。新的長(zhǎng)期支持版本每三年發(fā)布一次,根據(jù)后續(xù)的發(fā)布計(jì)劃,下一個(gè)長(zhǎng)期支持版 Java 17 將于2021年發(fā)布
【白嫖資料】
1.3 目前企業(yè)JDK版本使用現(xiàn)狀
在 JDK 版本的世界里,從來都是 Oracle 發(fā)他的新版本,我們繼續(xù)用我們的老版本。三年之前用 JDK 7,后來終于升級(jí)到了 JDK 8。自從升級(jí)了沒多久,JDK 就開始了半年發(fā)一個(gè)新版本的節(jié)奏,陸續(xù)發(fā)布了 9 、10、11、12,直到(2019年9月17日)發(fā)布了 JDK13。
開發(fā)人員在生產(chǎn)中為其應(yīng)用程序使用了哪些產(chǎn)品?我們可以看到Oracle JDK和OpenJDK在其他所有人的主導(dǎo)地位。2018年12月,由 Snyk 和 The Java Magazine 聯(lián)合推出發(fā)布的 2018 JVM 生態(tài)調(diào)查報(bào)告 顯示有 70% 的用戶使用 Oracle JDK,21% 的用戶使用 OpenJDK。
Java 9中的JDK進(jìn)行了重大的結(jié)構(gòu)更改,許多人預(yù)測(cè)這將影響遷移和采用。從結(jié)果中我們可以看到(請(qǐng)注意,調(diào)查是在Java 10和Java 11發(fā)行之間進(jìn)行的),Java 8仍然是Java的最主要版本-十分之八的受訪者表示,他們的主要應(yīng)用程序在生產(chǎn)中使用了Java 8。同樣重要的是,使用更新版本的非Java 8受訪者不到一半。2018 JVM 生態(tài)調(diào)查報(bào)告](https://snyk.io/blog/jvm-ecosystem-report-2018
,其中 Java 8 的使用者占到了 79%。
1.4 JDK 13詳細(xì)概述
2019年9月17日,國(guó)際知名的OpenJDK開源社區(qū)發(fā)布了Java編程語言環(huán)境的最新版本OpenJDK 13,此次更新是繼半年前 Java 12 這大版本發(fā)布之后的一次常規(guī)版本更新,在這一版中,主要帶來了 ZGC 增強(qiáng)、更新 Socket 實(shí)現(xiàn)、Switch
表達(dá)式,文本塊更新等方面的改動(dòng)、增強(qiáng)。
1.5 JDK 13 新特性更新列表介紹
PROPERTIES
網(wǎng)站:http://openjdk.java.net/projects/jdk/13/
[圖片上傳失敗...(image-637372-1625485911751)]
1.6 啟動(dòng)IDEA創(chuàng)建模塊集成JDK 13
- 去官網(wǎng)下載JDK 13
- 下載地址:https://www.oracle.com/java/technologies/javase-jdk13-downloads.html
- 啟動(dòng)IDEA創(chuàng)建一個(gè)模塊集成JDK 13
JDK 13新特性詳解
2.1 JEP 354 switch表達(dá)式(預(yù)覽)
引入
擴(kuò)展switch分支選擇語句的寫法。Switch表達(dá)式在經(jīng)過JDK 12的預(yù)覽之后,在JDK 13中可以繼續(xù)使用。
設(shè)計(jì)初衷
Java的switch語句是一個(gè)變化較大的語法(可能是因?yàn)镴ava的switch
語句一直不夠強(qiáng)大、熟悉swift或者js語言的同學(xué)可與swift的switch語句對(duì)比一下,就會(huì)發(fā)現(xiàn)Java的switch
相對(duì)較弱),因?yàn)镴ava的很多版本都在不斷地改進(jìn)switch語句:JDK 12擴(kuò)展了switch語句,使其可以用作語句或者表達(dá)式,并且傳統(tǒng)的和擴(kuò)展的簡(jiǎn)化版switch都可以使用。【白嫖資料】
JDK 12對(duì)于switch的增強(qiáng)主要在于簡(jiǎn)化書寫形式,提升功能點(diǎn)。
下面簡(jiǎn)單回顧一下switch的進(jìn)化階段:
- 從Java 5+開始,Java的switch語句可使用枚舉了。
- 從Java 7+開始,Java的switch語句支持使用String類型的變量和表達(dá)式了。
- 從Java 11+開始,Java的switch語句會(huì)自動(dòng)對(duì)省略break導(dǎo)致的貫穿提示警告。
- 但從JDK12開始,Java的switch語句有了很大程度的增強(qiáng)。
- JDK 13的該JEP是從JEP 325]演變而來的。
以前的switch程序
代碼如下:
public class Demo01{
public static void main(String[] args){
// 聲明變量score,并為其賦值為'C'
var score = 'C';
// 執(zhí)行switch分支語句
switch (score) {
case 'A':
System.out.println("優(yōu)秀");
break;
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("中");
break;
case 'D':
System.out.println("及格");
break;
case 'E':
System.out.println("不及格");
break;
default:
System.out.println("數(shù)據(jù)非法!");
}
}
}
這是經(jīng)典的Java 11以前的switch
寫法 ,這里不能忘記寫break
,否則switch
就會(huì)貫穿、導(dǎo)致程序出現(xiàn)錯(cuò)誤(JDK 11會(huì)提示警告)。
JDK 13不需要break了
在JDK 12
之前如果switch忘記寫break將導(dǎo)致貫穿,在JDK 12對(duì)switch
的這一貫穿性做了改進(jìn)。你只要將case后面的冒號(hào)(:)改成箭頭,那么你即使不寫break也不會(huì)貫穿了,因此上面程序可改寫如下形式:
public class Demo02{
public static void main(String[] args){
// 聲明變量score,并為其賦值為'C'
var score = 'C';
// 執(zhí)行switch分支語句
switch (score){
case 'A' -> System.out.println("優(yōu)秀");
case 'B' -> System.out.println("良好");
case 'C' -> System.out.println("中");
case 'D' -> System.out.println("及格");
case 'E' -> System.out.println("不及格");
default -> System.out.println("成績(jī)數(shù)據(jù)非法!");
}
}
}
上面代碼簡(jiǎn)潔很多了。
JDK 13的switch表達(dá)式
JDK 12之后的switch甚至可作為表達(dá)式了——不再是單獨(dú)的語句。例如如下程序。
public class Demo03 {
public static void main(String[] args) {
// 聲明變量score,并為其賦值為'C'
var score = 'C';
// 執(zhí)行switch分支語句
String s = switch (score)
{
case 'A' -> "優(yōu)秀";
case 'B' -> "良好";
case 'C' -> "中";
case 'D' -> "及格";
case 'F' -> "不及格";
default -> "成績(jī)輸入錯(cuò)誤";
};
System.out.println(s);
}
}
上面程序直接將switch表達(dá)式的值賦值給s變量,這樣switch
不再是一個(gè)語句,而是一個(gè)表達(dá)式.
JDK 13中switch的多值匹配
當(dāng)你把switch中的case
后的冒號(hào)改為箭頭之后,此時(shí)switch就不會(huì)貫穿了,但在某些情況下,程序本來就希望貫穿比如我就希望兩個(gè)case共用一個(gè)執(zhí)行體!JDK 12之后的switch中的case也支持多值匹配,這樣程序就變得更加簡(jiǎn)潔了。例如如下程序。
public class Demo04 {
public static void main(String[] args) {
// 聲明變量score,并為其賦值為'C'
var score = 'B';
// 執(zhí)行switch分支語句
String s = switch (score)
{
case 'A', 'B' -> "上等";
case 'C' -> "中等";
case 'D', 'E' -> "下等";
default -> "成績(jī)數(shù)據(jù)輸入非法!";
};
System.out.println(s);
}
}
JDK 13的Yielding a value
當(dāng)使用箭頭標(biāo)簽時(shí),箭頭標(biāo)簽右邊可以是表達(dá)式、throw
語句或是代碼塊。如果是代碼塊,需要使用yield
語句來返回值。下面代碼中的print方法中的default
語句的右邊是一個(gè)代碼塊。在代碼塊中使用yield
來返回值。,JDK 13引入了一個(gè)新的yield
語句來產(chǎn)生一個(gè)值,該值成為封閉的switch表達(dá)式的值。
public void print(int days) {
// 聲明變量score,并為其賦值為'C'
var score = 'B';
String result = switch (score) {
case 'A', 'B' -> "上等";
case 'C' -> "中等";
case 'D', 'E' -> "下等";
default -> {
if (score > 100) {
yield "數(shù)據(jù)不能超過100";
} else {
yield score + "此分?jǐn)?shù)低于0分";
}
}
};
System.out.println(result);
}
在switch
表達(dá)式中不能使用break
。switch
表達(dá)式的每個(gè)標(biāo)簽都必須產(chǎn)生一個(gè)值,或者拋出異常。switch
表達(dá)式必須窮盡所有可能的值。這意味著通常需要一個(gè)default
語句。一個(gè)例外是枚舉類型。如果窮盡了枚舉類型的所有可能值,則不需要使用default
。【白嫖資料】
在這種情況下,編譯器會(huì)自動(dòng)生成一個(gè)default
語句。這是因?yàn)槊杜e類型中的枚舉值可能發(fā)生變化。比如,枚舉類型Color
中原來只有3個(gè)值:RED
、GREEN
和BLUE
。使用該枚舉類型的switch
表達(dá)式窮盡了3種情況并完成編譯。之后Color
中增加了一個(gè)新的值YELLOW
,當(dāng)用這個(gè)新的值調(diào)用之前的代碼時(shí),由于不能匹配已有的值,編譯器產(chǎn)生的default
會(huì)被調(diào)用,告知枚舉類型發(fā)生改變
小結(jié)
從以上案例可以看出JDK 12到JDK 13
對(duì)switch的功能做了很大的改進(jìn),代碼也十分的簡(jiǎn)化,目前來看switch依然是不支持區(qū)間匹配的,未來是否可以支持,我們拭目以待。
2.2 JEP 355 文本塊升級(jí)(預(yù)覽)
引入
在Java中,在字符串文字中嵌入HTML,XML,SQL或JSON
片段"..."
通常需要先進(jìn)行轉(zhuǎn)義和串聯(lián)的大量編輯,然后才能編譯包含該片段的代碼。該代碼段通常難以閱讀且難以維護(hù),因此,如果具有一種語言學(xué)機(jī)制,可以比多行文字更直觀地表示字符串,而且可以跨越多行,而且不會(huì)出現(xiàn)轉(zhuǎn)義的視覺混亂,那么這將提高廣泛Java類程序的可讀性和可寫性。從JDK 13
到JDK 13
開始文本塊新特性的提出,提高了Java程序書寫大段字符串文本的可讀性和方便性。
HTML示例
使用“一維”字符串文字*
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
使用“二維”文本塊
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
System.out.println("""
Hello,
itheima
text blocks!
""");
文本塊是Java語言的新語法,可以用來表示任何字符串,具有更高的表達(dá)能力和更少的復(fù)雜度。文本塊的開頭定界符是由三個(gè)雙引號(hào) """ 開始,從新的一行開始字符串的內(nèi)容。這里的新起的這行不屬于字符串,只表示內(nèi)容開始,是語法的一部分。以 """ 結(jié)束。 """ 可以緊跟字符串內(nèi)容,也可以另起一行。另起一行時(shí),字符串內(nèi)容最后會(huì)留有一新行。
"""
line 1
line 2
line 3
"""
等效于字符串文字:
"line 1\nline 2\nline 3\n"
或字符串文字的串聯(lián):
`"line 1\n" +
"line 2\n" +
"line 3\n"
如果在字符串的末尾不需要行終止符,則可以將結(jié)束定界符放在內(nèi)容的最后一行。例如,文本塊:
"""
line 1
line 2
line 3"""`
等效于字符串文字:
"line 1\nline 2\nline 3"
文本塊可以表示空字符串,盡管不建議這樣做,因?yàn)樗枰獌尚性创a:
String empty = """
""";
以下是一些格式錯(cuò)誤的文本塊的示例:
String a = """"""; // no line terminator after opening delimiter
String b = """ """; // no line terminator after opening delimiter
String c = """
"; // no closing delimiter (text block continues to EOF)
String d = """
abc \ def
"""; // unescaped backslash (see below for escape processing)
HTML
使用原始字符串語法:
String html = "<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";
使用文本塊文本塊語法:
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
SQL
使用原始的字符串語法:
`String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
"WHERE `CITY` = 'INDIANAPOLIS'\n" +
"ORDER BY `EMP_ID`, `LAST_NAME`;\n";
使用文本塊語法:
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";
多語言示例
使用原始的字符串語法:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("function hello() {\n" +
" print('\"Hello, world\"');\n" +
"}\n" +
"\n" +
"hello();\n");
使用文本塊語法:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
function hello() {
print('"Hello, world"');
}
hello();
""");
縮進(jìn)
java編譯器會(huì)自動(dòng)刪除不需要的縮進(jìn):
- 每行結(jié)尾的空格都會(huì)刪除
- 每行開始的共有的空格會(huì)自動(dòng)刪除
- 只保留相對(duì)縮進(jìn)。
System.out.println("""
Hello,
itheima
text blocks!
""");
// 結(jié)果
// > Hello,
// > itheima
// > text blocks!
// >
System.out.println("""
Hello,
itheima
text blocks!
""");
// 結(jié)果
// > Hello,
// > itheima
// > text blocks!
// >
- 新行 """ 結(jié)束時(shí),將 """ 向左調(diào)整,則可以給所有行前加相應(yīng)數(shù)量的空格。將 """ 向右調(diào)整,沒有作用。
System.out.println("""
Hello,
multiline
text blocks!
""");
// 結(jié)果
// > Hello,
// > multiline
// > text blocks!
2.3 JEP 350 動(dòng)態(tài)類數(shù)據(jù)共享歸檔
作用:允許在Java應(yīng)用程序執(zhí)行結(jié)束時(shí)動(dòng)態(tài)歸檔類。歸檔的類將包括默認(rèn)基層CDS歸檔中不存在的所有已加載應(yīng)用程序類和庫(kù)類。
CDS,是java 12的特性了,可以讓不同 Java 進(jìn)程之間共享一份類元數(shù)據(jù),減少內(nèi)存占用,它還能加快應(yīng)用的啟動(dòng)速度。而JDK13
的這個(gè)特性支持在Java application
執(zhí)行之后進(jìn)行動(dòng)態(tài)archive
。存檔類將包括默認(rèn)的基礎(chǔ)層CDS存檔中不存在的所有已加載的應(yīng)用程序和庫(kù)類。也就是說,在Java 13中再使用AppCDS
的時(shí)候,就不再需要這么復(fù)雜了。該提案處于目標(biāo)階段,旨在提高AppCDS的可用性,并消除用戶進(jìn)行試運(yùn)行以創(chuàng)建每個(gè)應(yīng)用程序的類列表的需要。
目標(biāo)
JDK13這次對(duì)CDS增強(qiáng)的主要目的
- 改善
AppCDS
的可用性,減少用戶每次都要?jiǎng)?chuàng)建一個(gè)類列表的需要 - 通過開啟,
-Xshare:dump
選項(xiàng)來開啟靜態(tài)歸檔,使用類列表仍然行得通。會(huì)包含內(nèi)置的類加載信息和用戶定義的類加載信息
意義
在JDK13中做的增強(qiáng),可以只開啟命令行選項(xiàng)完成上面過程,在程序運(yùn)行的時(shí)候,動(dòng)態(tài)評(píng)估那些類需要?dú)w檔,同時(shí)支持內(nèi)置的類加載器和用戶定義的類加載器。【白嫖資料】
在第一次程序執(zhí)行完成之后,會(huì)自動(dòng)的將類進(jìn)行歸檔,后續(xù)在啟動(dòng)項(xiàng)目的時(shí)候也無需指定要使用哪些歸檔,整個(gè)過程看起來更加的透明。
2.4 JEP 351 ZGC 增強(qiáng): ZGC 釋放未使用內(nèi)存
目標(biāo)
作用:將未使用的堆內(nèi)存還給系統(tǒng)(即未提交的內(nèi)存空間)
詳解
ZGC 是 Java 11 中引入的最為矚目的垃圾回收特性,是一種可伸縮、低延遲的垃圾收集器,不過在 Java 11 中是實(shí)驗(yàn)性的引入,主要用來改善 GC 停頓時(shí)間,并支持幾百 MB 至幾個(gè) TB 級(jí)別大小的堆,并且應(yīng)用吞吐能力下降不會(huì)超過 15%,目前只支持 Linux/x64
位平臺(tái)的這樣一種新型垃圾收集器。
通過在實(shí)際中的使用,發(fā)現(xiàn) ZGC
收集器中并沒有像 Hotspot 中的 G1
和 Shenandoah
垃圾收集器一樣,能夠主動(dòng)將未使用的內(nèi)存釋放給操作系統(tǒng)的功能。對(duì)于大多數(shù)應(yīng)用程序來說,CPU 和內(nèi)存都屬于有限的緊缺資源,特別是現(xiàn)在使用的云上或者虛擬化環(huán)境中。【白嫖資料】
如果應(yīng)用程序中的內(nèi)存長(zhǎng)期處于空閑狀態(tài),并且還不能釋放給操作系統(tǒng),這樣會(huì)導(dǎo)致其他需要內(nèi)存的應(yīng)用無法分配到需要的內(nèi)存,而這邊應(yīng)用分配的內(nèi)存還處于空閑狀態(tài),處于"忙的太忙,閑的太閑"的非公平狀態(tài),并且也容易導(dǎo)致基于虛擬化的環(huán)境中,因?yàn)檫@些實(shí)際并未使用的資源而多付費(fèi)的情況。由此可見,將未使用內(nèi)存釋放給系統(tǒng)主內(nèi)存是一項(xiàng)非常有用且亟需的功能。
Java 13 中對(duì) ZGC 的改進(jìn),主要體現(xiàn)在下面幾點(diǎn):
- 釋放未使用內(nèi)存給操作系統(tǒng)
- 支持最大堆大小為 16TB
Java 13 中,ZGC 內(nèi)存釋放功能,默認(rèn)情況下是開啟的,不過可以使用參數(shù):-XX:-ZUncommit
顯式關(guān)閉。
2.5 JEP 353 重新實(shí)現(xiàn)舊版Socket API
引入
現(xiàn)在已有的java.net.Socket
和 java.net.ServerSocket
以及它們的實(shí)現(xiàn)類,都可以回溯到 JDK 1.0 時(shí)代了。原始socket的維護(hù)和調(diào)試都很痛苦。實(shí)現(xiàn)類還使用了線程棧作為 I/O 的緩沖,導(dǎo)致在某些情況下還需要增加線程棧的大小。該實(shí)現(xiàn)還存在幾個(gè)并發(fā)問題,需要徹底解決。在未來的網(wǎng)絡(luò)世界,要快速響應(yīng),不能阻塞本地方法線程,當(dāng)前的實(shí)現(xiàn)不適合使用了。
詳解
新的實(shí)現(xiàn)類
在 Java 13 之前,通過使用 PlainSocketImpl
作為 SocketImpl
的具體實(shí)現(xiàn)。
Java 13 中的新底層實(shí)現(xiàn),引入 NioSocketImpl
的實(shí)現(xiàn)用以替換 SocketImpl
的 PlainSocketImpl
實(shí)現(xiàn),此實(shí)現(xiàn)與 NIO(新 I/O)實(shí)現(xiàn)共享相同的內(nèi)部基礎(chǔ)結(jié)構(gòu),并且與現(xiàn)有的緩沖區(qū)高速緩存機(jī)制集成在一起,因此不需要使用線程堆棧。除了這些更改之外,還有其他一些更便利的更改,如使用 java.lang.ref.Cleaner
機(jī)制來關(guān)閉套接字(如果 SocketImpl
實(shí)現(xiàn)在尚未關(guān)閉的套接字上被進(jìn)行了垃圾收集),以及在輪詢時(shí)套接字處于非阻塞模式時(shí)處理超時(shí)操作等方面。
全新實(shí)現(xiàn)的NioSocketImpl
來替換JDK1.0的PlainSocketImpl
。
- 它便于維護(hù)和調(diào)試,與
NewI/O (NIO)
使用相同的 JDK 內(nèi)部結(jié)構(gòu),因此不需要使用系統(tǒng)本地代碼。 - 它與現(xiàn)有的緩沖區(qū)緩存機(jī)制集成在一起,這樣就不需要為 I/O 使用線程棧。
- 它使用
java.util.concurrent
鎖,而不是synchronized
同步方法,增強(qiáng)了并發(fā)能力。 - 新的實(shí)現(xiàn)是Java 13中的默認(rèn)實(shí)現(xiàn),但是舊的實(shí)現(xiàn)還沒有刪除,可以通過設(shè)置系統(tǒng)屬性
jdk.net.usePlainSocketImpl
來切換到舊版本。
代碼說明
運(yùn)行一個(gè)實(shí)例化Socket和ServerSocket
的類將顯示這個(gè)調(diào)試輸出。這是默認(rèn)的(新的)。
Module java.base
Package java.net
Class SocketImpl
public abstract class SocketImpl implements SocketOptions {
private static final boolean USE_PLAINSOCKETIMPL = usePlainSocketImpl();
private static boolean usePlainSocketImpl() {
PrivilegedAction<String> pa = () ->
NetProperties.get("jdk.net.usePlainSocketImpl");
String s = AccessController.doPrivileged(pa);
return (s != null) && !s.equalsIgnoreCase("false");
}
/**
Creates an instance of platform's SocketImpl
*/
@SuppressWarnings("unchecked")static <S extends SocketImpl & PlatformSocketImpl> S
createPlatformSocketImpl(boolean server) {
if (USE_PLAINSOCKETIMPL) {
return (S) new PlainSocketImpl(server);
} else {
return (S) new NioSocketImpl(server);
}
}
}
SocketImpl
的USE_PLAINSOCKETIMPL
取決于usePlainSocketImpl
方法,而它會(huì)從NetProperties
讀取
dk.net.usePlainSocketImpl配置,如果不為null且不為false,則usePlainSocketImpl方法返回true; createPlatformSocketImpl
會(huì)根據(jù)USE_PLAINSOCKETIMPL
來創(chuàng)建PlainSocketImpl
或者NioSocketImpl
。
通過這些更改,Java Socket API
將更易于維護(hù),更好地維護(hù)將使套接字代碼的可靠性得到改善。同時(shí) NIO 實(shí)現(xiàn)也可以在基礎(chǔ)層面完成,從而保持 Socket
和ServerSocket
類層面上的不變。
2.6 其他特性
上面列出的是大方面的特性,除此之外還有一些api的更新及廢棄,主要見 JDK 13 Release Notes,這里舉幾個(gè)例
子。
https://jdk.java.net/13/release-notes
增加項(xiàng)
添加FileSystems.newFileSystem(Path, Map<String, ?>) Method
新的java.nio.ByteBuffer Bulk get/put Methods Transfer Bytes Without Regard to Buffer Position
支持Unicode 12.1
添加-XX:SoftMaxHeapSize Flag
,目前僅僅對(duì)ZGC起作用
ZGC
的最大heap大小增大到16TB
移除項(xiàng)
移除awt.toolkit System Property
移除Runtime Trace Methods
移除-XX:+AggressiveOpts
移除Two Comodo Root CA Certificates、Two DocuSign Root CA Certificates
移除內(nèi)部的com.sun.net.ssl
包
廢棄項(xiàng)
廢棄-Xverify:none及-noverify
廢棄rmic Tool
并準(zhǔn)備移除
廢棄javax.security.cert
并準(zhǔn)備移除
已知問題
不再支持Windows 2019 Core Server
使用ZIP File System (zipfs) Provider
來更新包含Uncompressed Entries
的ZIP或JAR可能造成文件損壞
最后
Java 在更新發(fā)布周期為每半年發(fā)布一次之后,在合并關(guān)鍵特性、快速得到開發(fā)者反饋等方面,做得越來越好。從 Java 11 到 Java 13,目前確實(shí)是嚴(yán)格保持半年更新的節(jié)奏。Java 13 版本的發(fā)布帶來了些新特性和功能增強(qiáng)、性能提升和改進(jìn)嘗試。
以上包含的5個(gè)特性,能夠改變開發(fā)者的編碼風(fēng)格的主要有Text Blocks
和Switch Expressions
兩個(gè)新特性,但是這兩個(gè)特性還處于預(yù)覽階段。
而且,JDK13并不是LTS(長(zhǎng)期支持)版本,如果你正在使用-Java 8(LTS)或者Java 11(LTS),暫時(shí)可以不必升級(jí)到Java 13。
最后,祝大家早日學(xué)有所成,拿到滿意offer,快速升職加薪,走上人生巔峰。
可以的話請(qǐng)給我一個(gè)三連支持一下我喲??????【白嫖資料】