新專案為什麼決定用 JDK 17了
來源:哪吒程式設計
大家好,我是哪吒。
Java是一門非常流行的程式語言,由於其跨平臺性、可移植性以及強大的物件導向特性而備受青睞。Java最初由Sun Microsystems公司於1995年推出,隨著時間的推移,Java發展迅速,版本不斷更新。本篇部落格將重點介紹Java 17與Java 8的對比,以及Java 17的新特性。
特徵 | Java 17 | Java 8 |
---|---|---|
引入 | 2021年9月14日 | 2014年3月 |
垃圾收集器 | ZGC(新型垃圾收集器) | G1收集器 |
其他垃圾收集器 | Shenandoah GC,G1 GC,Parallel GC,Serial GC | Parallel GC,Serial GC |
垃圾回收策略 | 全堆回收和增量模式 | 複製模式 |
應用程式類資料共享(AppCDS) | 支援 | 不支援 |
JFR事件流 | 使用非同步處理提高效能 | 未支援 |
條件性例項化卡片 | 支援 | 支援 |
嵌入式C / C ++庫 | JDK不包括C / C ++編譯器 | JDK不包括C / C ++編譯器 |
演算法升級 | SHA-3,SM3 / SM4,Ed448,RSASSA-PSS,X25519 / X448 | SHA-1,RC4,DES,MD5,DSA,DH |
一、Java 17與Java 8的對比
Java 17與Java 8是Java版本中的兩個重要里程碑。Java 8是Java版本中的一次重大更新,於2014年釋出,引入了很多新的特性和功能,包括Lambda表示式、Stream API、函式式介面等。Java 17是Java SE 17版本,於2021年9月釋出,是Java SE 16的長期支援(LTS)版本。Java 17中也有一些新的特性和改進,我們將在後文中詳細討論。
二、效能比較
Java 17與Java 8在效能方面的比較非常重要。Java 8引入了一些效能改進,例如最佳化了字串連線和陣列排序等操作。Java 17在效能方面也有一些新的改進,例如:
改進了JIT編譯器,提高了應用程式的效能。 改進了垃圾回收器,提高了垃圾回收的效率和吞吐量。 引入了C++風格的記憶體管理,包括對堆記憶體分配的最佳化和對垃圾回收的改進。這些改進都可以提高Java應用程式的效能和響應速度。
三、語言特性比較
Java 8引入了一些新的語言特性,例如Lambda表示式和函式式介面。這些特性讓Java程式設計師能夠使用函數語言程式設計的方式編寫程式碼,從而使得程式碼更加簡潔、易讀、易維護。Java 17在語言特性方面也有一些新的改進,例如:
引入了Sealed類,這是一種新的類修飾符,用於限制類的繼承。這樣可以使得程式碼更加安全、可維護。 引入了Pattern Matching for Switch語法,這是一種新的switch語法,可以用於模式匹配。這樣可以使得程式碼更加簡潔、易讀、易維護。 引入了Record類,這是一種新的資料類,可以用於定義只有屬性和訪問器的簡單資料物件。這樣可以使得程式碼更加簡潔、易讀、易維護。 這些改進都可以使得Java程式設計師能夠使用更加先進、更加高效的語言特性編寫程式碼。
四、應用場景比較
Java 8和Java 17都可以用於不同的應用場景,但是它們在一些方面有所不同。Java 8適用於開發中小型應用程式和Web應用程式,例如Web服務、企業級應用程式和桌面應用程式等。Java 8也可以用於開發大型應用程式,但是在大型應用程式中可能會出現一些效能問題。Java 17則更適合用於開發大型應用程式和高效能應用程式,例如高效能運算、雲端計算、大資料處理等。
五、Java 17的新特性
Java 17是Java SE 17版本,於2021年9月釋出,是Java SE 16的長期支援(LTS)版本。Java 17中有許多新的特性和改進,以下是一些主要特性:
1、Sealed類
Sealed類是一種新的類修飾符,用於限制類的繼承。Sealed類可以控制哪些類可以繼承自它,這樣可以使得程式碼更加安全、可維護。Sealed類的使用可以在編譯時強制執行一些規則,從而避免執行時錯誤。
(1)程式碼示例
public sealed abstract class Shape permits Circle, Rectangle {
public abstract double calculateArea();
}
public final class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public double calculateArea() {
return Math.PI * radius * radius;
}
}
public final class Rectangle extends Shape {
private double length;
private double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
public double getLength() {
return length;
}
public double getWidth() {
return width;
}
public double calculateArea() {
return length * width;
}
}
(2)程式碼說明:
在這個示例中,Shape 是一個抽象類,並且使用 permits 關鍵字,明確允許哪些類繼承該類。Circle 和 Rectangle 是 Shape 的子類,並使用 final 關鍵字來表示它們是封閉類,不允許有其他子類繼承它們。這種方式可以在編譯時校驗程式碼,並防止意外建立不受預期的子類。
2、Pattern Matching for Switch語法
Pattern Matching for Switch語法是一種新的switch語法,可以用於模式匹配。Pattern Matching for Switch語法可以根據不同的模式執行不同的操作,從而使得程式碼更加簡潔、易讀、易維護。Pattern Matching for Switch語法可以減少程式碼量,避免出現大量的if-else語句。
(1)程式碼示例
public static void main(String[] args) {
Object obj = "hello";
switch (obj) {
case String s && s.length() > 5 -> System.out.println("長字串");
case String s -> System.out.println("短字串");
case Integer i -> System.out.println("整型數");
default -> System.out.println("不支援的型別");
}
}
(2)程式碼說明:
在這個示例中,我們首先定義了一個 Object 型別的變數 obj,它可能是一個字串、整型數或其他型別的物件。
接下來,我們使用了 switch 語句,並對 obj 進行了幾個模式匹配:
如果 obj 是一個長度大於 5 的字串,表示式 case String s && s.length() > 5 就會被匹配並執行相應的程式碼塊。 如果 obj 是一個短字串,表示式 case String s 會匹配並執行相應程式碼塊。 如果 obj 是一個整型數,表示式 case Integer i 就會執行相應程式碼塊。 如果 obj 不屬於以上任何一種型別,就會執行預設程式碼塊。
3、Record類
Record類是一種新的資料類,可以用於定義只有屬性和訪問器的簡單資料物件。Record類可以簡化程式碼,使得程式碼更加易讀、易維護。Record類的使用可以減少程式碼量,避免出現大量的getter和setter方法。
(1)程式碼示例
public record Person(String name, int age) {}
public class RecordExample {
public static void main(String[] args) {
Person person = new Person("John", 30);
System.out.println("Name: " + person.name());
System.out.println("Age: " + person.age());
}
}
(2)程式碼說明:
在這個示例中,我們定義了一個名為 Person 的 Record 類,它有兩個欄位:name 和 age。Record 類會自動生成一個帶有這些欄位的建構函式、getter 方法和 equals、hashCode 和 toString 方法。
我們在 main 方法中建立了一個 Person 物件,並使用 name() 和 age() 方法獲取其名稱和年齡資訊,然後將其列印出來。
使用 Record 類,我們可以更輕鬆地定義簡單的資料類,而不需要手動編寫大量的建構函式和 getter 方法。這可以使我們的程式碼更加簡潔、清晰,並且更易於閱讀和維護。
4、改進的垃圾回收器
Java 17中改進了垃圾回收器,提高了垃圾回收的效率和吞吐量。改進的垃圾回收器可以更加高效地回收記憶體,從而提高應用程式的效能和響應速度。
(1)程式碼示例
public class GarbageCollectorExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
list.add(i);
}
System.out.println("List size: " + list.size());
System.gc(); // 呼叫垃圾回收器
System.out.println("List size after GC: " + list.size());
}
}
(2)程式碼說明:
在這個示例中,我們使用了 ZGC 垃圾回收器來回收 list 物件佔用的記憶體。我們在程式碼中使用了 System.gc() 方法來手動觸發垃圾回收器。注意,在實際應用中,我們通常不需要手動觸發垃圾回收器,因為 JVM 會自動進行垃圾回收操作。
ZGC 垃圾回收器具有可伸縮性和低延遲的特點,可以在處理大型、高併發應用程式時提供更好的效能和吞吐量。除了 ZGC,Java 17 中還引入了 Shenandoah 垃圾回收器,它也具有類似的高效能和低延遲的特點。
5、改進的JIT編譯器
Java 17中改進了JIT編譯器,提高了應用程式的效能。改進的JIT編譯器可以更加高效地編譯程式碼,從而提高應用程式的效能和響應速度。
(1)程式碼示例
public class JITCompilerExample {
public static void main(String[] args) {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
System.out.println("Sum is: " + sum);
}
}
在Java 17中,可以透過新增以下命令列引數來啟用Graal編譯器:
-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler
(2)程式碼說明:
當執行上述示例程式碼時,Graal編譯器會自動將迴圈最佳化為一個簡單的算術公式,從而大大提高了效能。
6、風格的記憶體管理
Java 17中引入了C++風格的記憶體管理,包括對堆記憶體分配的最佳化和對垃圾回收的改進。C++風格的記憶體管理可以使得Java應用程式更加高效,從而提高應用程式的效能和響應速度。
(1)程式碼示例
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.ManagementFactory;
public class MemoryManagementExample {
public static void main(String[] args) throws InterruptedException {
MemoryPoolMXBean heap = ManagementFactory.getMemoryPoolMXBeans().stream()
.filter(p -> p.getName().equals("Java heap")).findFirst().orElseThrow();
System.out.println("Heap memory utilization statistics:\n");
try (var scope = heap.reserveMemory(1024 * 1024)) {
long usedMemory = heap.getUsage().getUsed();
long commitedMemory = heap.getUsage().getCommitted();
System.out.printf("Before allocation: used=%d, committed=%d%n", usedMemory, commitedMemory);
byte[] array = new byte[1024 * 1024];
usedMemory = heap.getUsage().getUsed();
int capacity = scope.getBytesReserved();
System.out.printf("After allocation: used=%d, committed=%d, capacity=%d%n", usedMemory, commitedMemory,
capacity);
}
long usedMemory = heap.getUsage().getUsed();
long commitedMemory = heap.getUsage().getCommitted();
System.out.printf("After scope: used=%d, committed=%d%n", usedMemory, commitedMemory);
}
}
(2)程式碼說明:
定義了一個名為 MemoryManagementExample 的類,然後獲取 Java heap 記憶體池,並在 try-with-resources 語句中建立了一個名為 scope 的資源。
然後,我們列印了記憶體使用率統計資訊,並在 scope 內部分配了一個 1MB 的位元組陣列。我們使用 getBytesReserved() 方法獲取作用域中已保留的位元組數,並列印了記憶體使用情況和容量等資訊。
最後,我們列印了作用域結束後記憶體的使用情況。
7、增強的Java集合庫
Java 17中增強了Java集合庫,包括新增了一些集合型別和對現有集合型別的改進。增強的Java集合庫可以提高開發人員的開發效率和程式碼質量,從而減少出現錯誤的可能性。同時,增強的Java集合庫也可以提高應用程式的效能和響應速度,使得Java應用程式更加高效。
(1)of() 方法:建立一個不可變的集合
List<String> list = List.of("apple", "banana", "orange");
Set<Integer> set = Set.of(1, 2, 3, 4);
Map<String, Integer> map = Map.of("apple", 1, "banana", 2, "orange", 3);
(2)forEach() 方法:遍歷集合
List<String> list = List.of("apple", "banana", "orange");
list.forEach(name -> System.out.println(name));
Set<Integer> set = Set.of(1, 2, 3, 4);
set.forEach(number -> System.out.println(number));
(3)Collectors類:提供了一系列的歸約操作
List<String> list = List.of("apple", "banana", "orange");
String joinedString = list.stream().collect(Collectors.joining("-", "[", "]"));
System.out.println(joinedString);
Map<String, Integer> map = Map.of("apple", 1, "banana", 2, "orange", 3);
Map<Integer, String> reversedMap = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
System.out.println(reversedMap);
(4)takeWhile() 方法和 dropWhile() 方法:根據條件擷取集合
List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7);
List<Integer> takenList = list.stream().takeWhile(number -> number < 5).collect(Collectors.toList());
System.out.println(takenList);
List<Integer> dropedList = list.stream().dropWhile(number -> number < 5).collect(Collectors.toList());
System.out.println(dropedList);
(5)toArray(IntFunction<T[]>) 方法:返回集合中的所有元素到一個新陣列中
List<String> list = List.of("apple", "banana", "orange");
String[] array = list.toArray(String[]::new);
System.out.println(Arrays.toString(array));
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2952716/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 新專案決定用 JDK 17了JDK
- JDK17用什麼docker基礎映象?JDKDocker
- 為什麼RPA專案失敗了呢?
- JDK 17:Java 17 中的新特性 - InfoWorldJDKJava
- 為什麼iOS專案應該用CocoaPodsiOS
- 新專案為什麼要註冊新加坡基金會?
- 模型中到底什麼決定了效果模型
- 為什麼專案會延期?
- 我為什麼把失敗的創業專案開源了創業
- 我有點想用JDK17了JDK
- 為專案應用設定No-PIE
- JDK的第三個LTS版本JDK17來了JDK
- 為什麼很多大資料專案搞著搞著就黃了?大資料
- Service Mesh是什麼,為我們解決了什麼問題?
- 為什麼區塊鏈成為了企業“新常態”區塊鏈
- 為什麼Twitter決定採用kafka作為其釋出訂閱系統?Kafka
- 第18章_JDK8-17新特性JDK
- 為什麼Date物件被設定成過時了物件
- Spring Boot 2.5.6、JDK 17 和 Maven 的完整開源專案Spring BootJDKMaven
- 為什麼專案估算偏差如此之大?
- 資訊化為什麼需要專案管理?(轉)專案管理
- 專案研發為什麼失敗?(轉)
- 專案管理軟體可以解決什麼專案管理
- 專案註定延期時,應該做什麼?
- 為什麼企業需要專用核心網?
- 為什麼不在標頭檔案做定義
- 為什麼專案老夭折?這份專案管理指南請收好專案管理
- 自下而上的專案用什麼專案管理工具好?專案管理
- 運維專案管理用什麼專案管理軟體好?運維專案管理
- JDK6.0與JDK4.0相比有什麼新特性JDK
- 是什麼決定了雲端計算在中國的發展
- 為什麼軟體專案的費用支出總是過高(轉)
- 為什麼在安裝jdk的時候要設定環境變數JDK變數
- [翻譯]JDK8有什麼新東西?JDK
- Oracle ASM有什麼用?為什麼用?OracleASM
- JDK11升級JDK17最全實踐乾貨來了JDK
- 企業為什麼要進行專案控制?
- 討論:你的專案為什麼不迭代?