最後,JDK 12作為六個月發佈一次的一部分,終於來了。這是繼上一個Java LTS版本11之後的版本。我們之前詳細討論過Java 11的功能。今天我們將討論Java 12的功能,並看看它為開發人員提供了什麼。Java 12於2019年3月19日發佈。這是一個非LTS版本。因此,它不會有長期支持。
Java 12的功能
一些重要的Java 12功能包括:
- JVM更改- JEP 189,JEP 346,JEP 344和JEP 230。
- Switch表達式
- File mismatch()方法
- 緊湊數字格式化
- 在Stream API中使用Teeing Collectors
- Java字符串新方法- indent(),transform(),describeConstable()和resolveConstantDesc()。
- JEP 334:JVM常量API
- JEP 305:instanceof的模式匹配
- 在JDK 12中刪除了原始字符串文字。
讓我們逐一研究所有這些Java 12功能。
JVM更改
1. JEP 189 – Shenandoah: 低暫停時間垃圾收集器 (實驗性)
RedHat發起了Shenandoah垃圾收集器,以減少GC暫停時間。其思想是與運行中的Java線程並行運行GC,旨在實現不管堆大小是15MB還是15GB,都能保持一致且可預測的短暫停。這是Java 12中的實驗性功能。
2. JEP 346 – 及時從G1返回未使用的已分配內存
自Java 12起,G1將在應用程序閒置時檢查Java堆內存並將其返回給操作系統。這是一種預防性措施,以保存並使用空閒內存。
3. JEP 344:G1的可中斷混合收集
G1 效能的改進包括使 G1 混合收集可中止,如果它們可能超過定義的暫停目標。這是通過將混合收集集分為強制和可選來完成的。因此,G1 收集器可以優先收集強制集,以達到暫停時間目標。
4. JEP 230 和 344
Microbenchmark Suite, JEP 230 功能將一套基本的微基準加入到 JDK 源代碼中。這使得開發人員可以輕鬆運行現有的微基準並創建新的微基準。One AArch64 Port, Not Two, JEP 344,刪除了所有與 arm64 端口相關的源代碼,同時保留了 32 位 ARM 端口和 64 位 aarch64 端口。這使貢獻者可以將精力集中在單個 64 位 ARM 實現上。
5. JEP 341 默認 CDS 存檔
這增強了 JDK 構建過程,以在 64 位平台上使用默認類列表生成類數據共享(CDS)存檔。目標是提高啟動時間。從 Java 12 開始,CDS 默認為開啟狀態。要關閉 CDS 運行您的程序,請執行以下操作:
java -Xshare:off HelloWorld.java
現在,這將延遲程序的啟動時間。
語言變更與功能
Java 12引入了許多語言功能。讓我們看一些具體的實現。
1. Switch 表達式(預覽)
Java 12已增強了Switch表達式以進行模式匹配。在JEP 325中介紹的新語言功能作為預覽,新的語法是L ->
。以下是關於Switch表達式的一些注意事項:
- 新的語法不再需要break語句來防止“落入”。
- Switch表達式不再“落入”。
- 此外,我們可以在同一標籤中定義多個常量。
default
情況現在在Switch表達式中是強制的。break
在Switch表達式中用於從案例本身返回值。
經典的switch語句:
String result = "";
switch (day) {
case "M":
case "W":
case "F": {
result = "MWF";
break;
}
case "T":
case "TH":
case "S": {
result = "TTS";
break;
}
};
System.out.println("Old Switch Result:");
System.out.println(result);
使用新的Switch表達式,我們不需要在各處設置break,從而防止邏輯錯誤!
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(day.isEmpty())
break "Please insert a valid day.";
else
break "Looks like a Sunday.";
}
};
System.out.println(result);
讓我們運行包含新Switch表達式的以下程序,使用JDK 12。
public class SwitchExpressions {
public static void main(String[] args)
{
System.out.println("New Switch Expression result:");
executeNewSwitchExpression("M");
executeNewSwitchExpression("TH");
executeNewSwitchExpression("");
executeNewSwitchExpression("SUN");
}
public static void executeNewSwitchExpression(String day){
String result = switch (day) {
case "M", "W", "F" -> "MWF";
case "T", "TH", "S" -> "TTS";
default -> {
if(day.isEmpty())
break "Please insert a valid day.";
else
break "Looks like a Sunday.";
}
};
System.out.println(result);
}
}
由於這是一個預覽功能,請確保您已選擇語言級別為Java 12預覽。要編譯上述代碼,運行以下命令:
javac -Xlint:preview --enable-preview -source 12 src/main/java/SwitchExpressions.java
運行編譯後的程序後,在控制台中獲得以下結果

。Switch表達式是一個預覽語言功能。這意味著即使它是完整的,也可能不會在未來的Java版本中確認。
2. File.mismatch方法
Java 12添加了以下方法來比較兩個文件:
public static long mismatch(Path path, Path path2) throws IOException
此方法返回第一個不匹配的位置,如果沒有不匹配則返回-1L。兩個文件可能在以下情況下不匹配:
- 如果字節不相同。在這種情況下,返回第一個不匹配字節的位置。
- 文件大小不相同。在這種情況下,返回較小文件的大小。
下面是從IntelliJ Idea中的示例代碼片段:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class FileMismatchExample {
public static void main(String[] args) throws IOException {
Path filePath1 = Files.createTempFile("file1", ".txt");
Path filePath2 = Files.createTempFile("file2", ".txt");
Files.writeString(filePath1,"JournalDev Test String");
Files.writeString(filePath2,"JournalDev Test String");
long mismatch = Files.mismatch(filePath1, filePath2);
System.out.println("File Mismatch position... It returns -1 if there is no mismatch");
System.out.println("Mismatch position in file1 and file2 is >>>>");
System.out.println(mismatch);
filePath1.toFile().deleteOnExit();
filePath2.toFile().deleteOnExit();
System.out.println();
Path filePath3 = Files.createTempFile("file3", ".txt");
Path filePath4 = Files.createTempFile("file4", ".txt");
Files.writeString(filePath3,"JournalDev Test String");
Files.writeString(filePath4,"JournalDev.com Test String");
long mismatch2 = Files.mismatch(filePath3, filePath4);
System.out.println("Mismatch position in file3 and file4 is >>>>");
System.out.println(mismatch2);
filePath3.toFile().deleteOnExit();
filePath4.toFile().deleteOnExit();
}
}
上述Java程序編譯並運行時的輸出是:

3.緊湊的數字格式
import java.text.NumberFormat;
import java.util.Locale;
public class CompactNumberFormatting {
public static void main(String[] args)
{
System.out.println("Compact Formatting is:");
NumberFormat upvotes = NumberFormat
.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT);
upvotes.setMaximumFractionDigits(1);
System.out.println(upvotes.format(2592) + " upvotes");
NumberFormat upvotes2 = NumberFormat
.getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
upvotes2.setMaximumFractionDigits(2);
System.out.println(upvotes2.format(2011) + " upvotes");
}
}

4. 分流收集器
分流收集器是在 Streams API 中引入的新收集器实用程序。此收集器有三个参数 – 两个收集器和一个双功能。所有输入值都传递给每个收集器,结果可在双功能中获得。
double mean = Stream.of(1, 2, 3, 4, 5)
.collect(Collectors.teeing(
summingDouble(i -> i),
counting(),
(sum, n) -> sum / n));
System.out.println(mean);
输出为3.0。
5. Java 字符串新方法
Java 12 中引入了 4 个新方法,它们是:
- indent(int n)
- transform(Function f)
- Optional describeConstable()
- String resolveConstantDesc(MethodHandles.Lookup lookup)
要详细了解上述方法及其实现,请参阅我们的Java 12 字符串方法教程。
6. JEP 334: JVM 常量 API
A new package java.lang.constant
is introduced with this JEP. This is not that useful for those developers who don’t use constants pool.
7. JEP 305:instanceof 的模式匹配(預覽)
另一個預覽語言功能!將一種類型轉換為另一種類型的舊方法是:
if (obj instanceof String) {
String s = (String) obj;
// 從這裡開始在您的代碼中使用 s
}
新方法是:
if (obj instanceof String s) {
// 可以直接在這裡使用 s
}
這樣可以節省一些不必要的類型轉換。
在 JDK 12 中,原始字符串文字已被移除。
這就是有關 Java 12 功能的文章的結束。
Source:
https://www.digitalocean.com/community/tutorials/java-12-features