都要Java 20了你還在玩Java 8?
#01 Java版本演進(jìn) ?
? ? ? ? 從第一個(gè)1995年發(fā)布的alpha和beta Java公開(kāi)版本到即將發(fā)布的Java20, 已經(jīng)有28個(gè)年頭。這期間也發(fā)布了20多個(gè)版本,但其中被大家常用的也就幾個(gè)版本,甚至現(xiàn)在好多應(yīng)用還在用著Java8。
???????在我們選擇jdk版本的時(shí)候,盡量選擇LTS(長(zhǎng)期支持)版本,LTS 版本被認(rèn)為是最穩(wěn)定的版本,它經(jīng)歷了廣泛的測(cè)試,并且大多包含了多年積累的改進(jìn)。需要注意的是,LTS 版本的軟件不一定涉及功能更新,除非有一個(gè)更新的 LTS 版本。但是,你會(huì)在 LTS 版本的更新中得到必要的錯(cuò)誤修復(fù)和安全修復(fù)。
? ? ? ?Java 17, 11, 8 為目前提供支持的 LTS版本;Java 10 是上一個(gè)快速發(fā)布版本,且已不再被支持。2018年9月,隨著 Java 11 的發(fā)布,Java 10 自當(dāng)日起不再被支持。Oracle 將在 2019 年 1 月前為商業(yè)用途中的 Java 8 長(zhǎng)期支持,而針對(duì)非商用的更新將繼續(xù)提供,直至 2020 年 12 月;此外,AdoptOpenJDK 也為 Java 8 提供免費(fèi)更新。針對(duì) Java 11 的長(zhǎng)期支持將不再由 Oracle 提供,而是改由?OpenJDK?社區(qū)提供,例如 Eclipse Adoptium(以前稱之為 AdoptOpenJDK) 的 Eclipse Temurin。

#02 JDK?17 工具
? ? ? Jdk中自帶的工具可以給我們?cè)诖a開(kāi)發(fā)和維護(hù),性能調(diào)優(yōu)等方面給予巨大的幫助,我們有必要了解一下jdk17中自帶的一些開(kāi)發(fā)運(yùn)行工具。
2.1 所有平臺(tái)
-
jar?- 為類和資源創(chuàng)建存檔,并從存檔中操作或恢復(fù)單個(gè)類或資源
-
jarsigner?- 簽署并驗(yàn)證 Java 存檔 (JAR) 文件
-
java?- 啟動(dòng) Java 應(yīng)用程序
-
javac?- 讀取 Java 類和接口定義并將它們編譯成字節(jié)碼和類文件
-
javadoc?- 從 Java 源文件生成 API 文檔的 HTML 頁(yè)面
-
javap?- 反匯編一個(gè)或多個(gè)類文件
-
jcmd?- 向正在運(yùn)行的 Java 虛擬機(jī) (JVM) 發(fā)送診斷命令請(qǐng)求
-
jconsole?- 啟動(dòng)一個(gè)圖形控制臺(tái)來(lái)監(jiān)視和管理 Java 應(yīng)用程序
-
jdb?- 查找和修復(fù) Java 平臺(tái)程序中的錯(cuò)誤
-
jdeprscan?- 掃描 jar 文件(或其他一些類文件的集合)以查找已棄用的 API 元素的靜態(tài)分析工具
-
jdeps?- 啟動(dòng) Java 類依賴分析器
-
jfr?- 解析和打印飛行記錄器文件
-
jhsdb?- 附加到 Java 進(jìn)程或啟動(dòng)事后調(diào)試器以分析來(lái)自崩潰的 Java 虛擬機(jī) (JVM) 的核心轉(zhuǎn)儲(chǔ)的內(nèi)容
-
jinfo?- 為指定的 Java 進(jìn)程生成 Java 配置信息
-
jlink?- 將一組模塊及其依賴項(xiàng)組裝并優(yōu)化為自定義運(yùn)行時(shí)映像
-
jmap?- 打印指定進(jìn)程的詳細(xì)信息
-
jmod?- 創(chuàng)建 JMOD 文件并列出現(xiàn)有 JMOD 文件的內(nèi)容
-
jpackage?- 打包一個(gè)獨(dú)立的 Java 應(yīng)用程序
-
jps?- 列出目標(biāo)系統(tǒng)上已檢測(cè)的 JVM
-
jrunscript?- 運(yùn)行支持交互和批處理模式的命令行腳本外殼
-
jshell?- 在讀取-評(píng)估-打印循環(huán) (REPL) 中交互式評(píng)估 Java 編程語(yǔ)言的聲明、語(yǔ)句和表達(dá)式
-
jstack?- 打印指定 Java 進(jìn)程的 Java 線程的 Java 堆棧跟蹤
-
jstat?- 監(jiān)控 JVM 統(tǒng)計(jì)信息
-
jstatd?- 監(jiān)控已檢測(cè)的 Java HotSpot 虛擬機(jī)的創(chuàng)建和終止
-
keytool?- 管理加密密鑰、X.509 證書(shū)鏈和可信證書(shū)的密鑰庫(kù)(數(shù)據(jù)庫(kù))
-
rmid?- 啟動(dòng)激活系統(tǒng)守護(hù)進(jìn)程,使對(duì)象能夠在 Java 虛擬機(jī) (JVM) 中注冊(cè)和激活
-
rmiregistry?- 在當(dāng)前主機(jī)的指定端口上創(chuàng)建并啟動(dòng)遠(yuǎn)程對(duì)象注冊(cè)表
-
serialver?- 以適合復(fù)制到進(jìn)化類中的形式返回一個(gè)或多個(gè)類的“serialVersionUID”
2.2 僅適用于 Windows
-
jabswitch?- 啟用或禁用 Java Access Bridge
-
jaccessinspector?- 使用 Java Accessibility Utilities API 檢查有關(guān) Java 虛擬機(jī)中對(duì)象的可訪問(wèn)信息
-
jaccesswalker?- 瀏覽特定 Java 虛擬機(jī)中的組件樹(shù)并在樹(shù)視圖中顯示層次結(jié)構(gòu)
-
javaw?- 在沒(méi)有控制臺(tái)窗口的情況下啟動(dòng) Java 應(yīng)用程序
-
kinit?- 獲取并緩存 Kerberos 票證授予票證
-
klist?- 顯示本地憑證緩存和密鑰表中的條目
-
ktab?- 管理存儲(chǔ)在本地密鑰表中的主體名稱和服務(wù)密鑰
#03 從JDK8到JDK17的代碼新特征
3.1 簡(jiǎn)潔的字符串函數(shù)
- isBlank():如果字符串為空或字符串僅包含空格(包括制表符),則返回 true。注意與isEmpty() 不同,isEmpty()僅在長(zhǎng)度為 0 時(shí)返回 true。
- lines():將字符串拆分為字符串流,每個(gè)字符串包含一行。
- strip() :分別從開(kāi)頭和結(jié)尾;
- stripLeading()/stripTrailing()僅開(kāi)始和僅結(jié)束刪除空格。
- repeat(int times):返回一個(gè)字符串,該字符串采用原始字符串并按指定的次數(shù)重復(fù)該字符串。
- readString():允許從文件路徑直接讀取到字符串。
- writeString(Path path):將字符串直接寫(xiě)入指定路徑處的文件。
- indent(int level):縮進(jìn)字符串的指定量。負(fù)值只會(huì)影響前導(dǎo)空格。
- transform(Function f):將給定的 lambda 應(yīng)用于字符串。
private void strFeatures() throws IOException {
????????//lines()方法示例,\n?\r可以換行
????????String?str?=?"Hello?\njava17?\n!\r";
Stream<String> lines = str.lines();
lines.forEach(System.out::println);
//readString()方法示例
Path path = Path.of("D:\\good.txt");
String text = Files.readString(path).strip() ;
System.out.println(text);
}
3.2 字符串塊
private void textBlocks() {
String textBlocks = """
{"name": "lisi",
"age": %d, "sex": "%s"}
?????????????????""".formatted(12, "男");
System.out.println(textBlocks);
}
3.3 record更簡(jiǎn)潔的類定義
? ?無(wú)需set/get方法和構(gòu)造函數(shù)
record User2(String name, Integer age) {
@Override
public String toString() {
return "User2[" +
"name='" + name + '\'' +
", age=" + age +
']';
}
@Override
public boolean equals(Object obj) {
return false;
}
@Override
public int hashCode() {
return 0;
}
}
3.4 簡(jiǎn)單的switch表達(dá)式
private void newSwitch() {
int size = 3;
String cn = switch (size) {
case 1 -> "一";
case 2 -> "二";
case 3 -> "三";
default -> "未知";
};
System.out.println(cn);
}
3.5?密封類
/**
??*?定義一個(gè)抽象密封類Vehicle?,它的實(shí)現(xiàn)類只能是Car?,?Bus這兩個(gè),
??*?其他的實(shí)現(xiàn)類均不允許
??*/
public abstract sealed class Vehicle permits Car, Bus {}
public final class Car extends Vehicle {
}
public final class Bus extends Vehicle{
}
3.6?? Vector 向量計(jì)算
? ? ? Vector 向量計(jì)算 API 是為了處理 SIMD(Single Instruction Multiple Data,單指令多數(shù)據(jù))類型的操作,即并行執(zhí)行的各種指令集。它利用支持向量指令的專用 CPU 硬件,并允許以管道的形式執(zhí)行此類指令。這種運(yùn)算方式可以讓開(kāi)發(fā)人員實(shí)現(xiàn)更高效的代碼,充分利用底層硬件的潛力。日常使用包括科學(xué)代數(shù)線性應(yīng)用程序、圖像處理、字符處理、繁重的算術(shù)應(yīng)用程序,以及任何需要對(duì)多個(gè)獨(dú)立操作數(shù)應(yīng)用一個(gè)運(yùn)算的應(yīng)用程序。? Vector 向量計(jì)算 API 是在 Java16 引入(參見(jiàn) Java16 的新特性),可以在運(yùn)行時(shí)借助 CPU 向量運(yùn)算指令,實(shí)現(xiàn)更優(yōu)的計(jì)算能力。在 Java17 中,針對(duì)性能和實(shí)現(xiàn)進(jìn)行了改進(jìn),包括字節(jié)向量與布爾數(shù)組之間進(jìn)行轉(zhuǎn)換。
???private?void?vectorCalc(){
final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_PREFERRED;
final float[] a = {1, 2, 3, 4};
final float[] b = {5, 6, 7, 8};
final float[] c = new float[3];
for (var i = 0; i < a.length; i += SPECIES.length()) {
var m = SPECIES.indexInRange(i, a.length);
var va = FloatVector.fromArray(SPECIES, a, i, m);
var vb = FloatVector.fromArray(SPECIES, b, i, m);
var vc = va.mul(vb);
vc.intoArray(c, i, m);
}
}
