狠狠撸

狠狠撸Share a Scribd company logo
Java 22 & 23 新功能介紹
Joseph Kuo (CyberJos)
VP of Technology @ NextDrive
About Me
? '93 QBasic、'96 C/C++、'99 Java
? 資訊教育、雲端影?、電?商務、
資安防駭、???為、智慧物聯
? JCConf、Oracle Groundbreakers、AWS Summit、
AWS Startup Day、物聯網年會、永續淨零論壇、…
? 軟體?程、後端技術、設計架構、雲端邊緣、
智慧物聯、永續能源、資安稽核、技術教學
? 希望能?輩?玩技術寫程式到?
Taiwan Java User Group
? FB:https://www.facebook.com/groups/twjug
? 官?網站:http://www.twjug.org/
? LINE 社群「Java 程式語?討論區」
Agenda
● 2024 State of Java Ecosystem
● New Features in 22 & 23
● What's Next in 24?
依照惯例,先来个版本统计
JCConf 2024 - Java 22 & 23 新功能介紹
2024 State of Java Ecosystem
Published by New Relic
2023 State of Java Ecosystem
● 2020/03 New Relic 第一次報告發表
● 2024/04 發表 2024 年度報告
● 統計了上百萬個應用程式的回報資料
● 報告資料僅包含了 2024 年向 New Relic 回報的應
用程式,不代表 Java 整體的使用情況
Source: https://newrelic.com/resources/report/2024-state-of-the-java-ecosystem
17 上升幅度 26.3%,搶下市佔第?
32.9%
1.4%
35.4%
28.8%
Oracle 重回寶座、Eclipse 後來居上
18.2%
20.8%
17.8%
Log4j 為最受歡迎的?誌框架
61.2%
76.4%
資料庫系統第?名為 Oracle
14.4%
17.3%
12.5%
New Features in 22 & 23
17 features in total
重點摘要
新?友善
並?開發
底層互動
新?友善
降低學習?檻,消除冗餘代碼
降低學習?檻,消除冗餘代碼
1. JEP 477:隱式宣告類別和實例 main ?法 (3rd Prev)
2. JEP 476:模組匯?宣告 (Prev)
3. JEP 482:彈性建構式主體 (2nd Prev)
4. JEP 456:未命名變數和模式
5. JEP 455:模式、instanceof 與 switch 的基礎型別 (Prev)
6. JEP 467:Markdown ?件註解
7. JEP 458:啟動多檔案的原始碼程式
開不了?的「安安你好」
// HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
} 1. 需學習 public 與繼承和套件存取
2. 需學習 static 與靜態和實例成員
3. 寫 class {} 但?不到(類別)
4. 傳 String[] 但沒?到(陣列、命令列)
5. 已沒?氣解釋 System.out.println …
實例 main ?法
// HelloWorld.java
public class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
} 1. 主?法不需要 public
2. 主?法不需要 static
3. 不需要傳?String[]
隱式宣告類別
// HelloWorld.java <- 檔名即為類別名稱
void main() {
System.out.println("Hello, World!");
}
1. 不需要 class {}
2. ?動建?隱式類別:
final class HelloWorld
extends Object
?動匯?新的 I/O ?法
// HelloWorld.java
// import static java.io.IO.*; // 預設靜態匯入
void main() {
println("Hello, World!");
}
1. void println(Object obj)
2. void print(Object obj)
3. String readln(String prompt)
使??式與限制
String hello() { return "Hello, "; }
String world = "World!";
void main() {
println(this.hello() + this.world);
}
1. 未被 class {} 包覆的視為隱式類別
2. 外部類別無法呼叫其建構式與靜態成員
3. 只允許預設無參數建構式
4. 不能實作介?
5. 必須要有合法的 main ?法
更複雜的例?
String hello() { return "Hello, "; }
void main() {
println(this.hello() + Test.get());
}
class Test { // 內部類別
static String get() {
String name = readln("Your name: "); // 從輸?讀值
return "" != name ? name : "World!";
}
}
程式進?點順序
1. 非 private 的 static void main(String[] a)
2. 非 private 的 static void main()
3. 非 private 的 void main(String[] a)
4. 非 private 的 void main()
DEMO
JEP 477:隱式宣告類別和實例主?法
● 實例或無參數的 main ?法
● 沒有 class 檔名 {} 包覆的內容建?隱式類別
● ?動 import static java.io.IO.*
● ?動 import module java.base
● 無法被其他類別引?或繼承
● 不適?於?型專案
模組匯?宣告
import module java.base; // 模組匯?
import static java.io.IO.*;
class ModuleImport {
void main() {
var list = List.of("World!", "All!", ":)");
var n = new Random().nextInt(list.size());
println("Hello, " + list.get(n));
}
}
模糊匯?的衝突解決
import module java.base; // java.util.Date
import module java.sql; // java.sql.Date
import java.sql.Date; // 單?型別匯?
1. 匯?多模組時會有匯?衝突
2. 需另外?型別匯?去指明
JEP 476:模組匯?宣告
● 匯?模組中的所有定義導出的型別
● 不需學習類別的套件階層
● 減少?量 import 語句
● 不影響現有 import 語句?為
● 會降低程式碼可讀性
● 查找某類別的套件名稱時會有點?苦
早期在建構時想檢查參數
class Sub extends Super {
public Sub(int i) {
super(check(i)); // 只能透過靜態?法檢查
}
static int check(int i) {
if (i == 0) throw new RuntimeException();
return i;
}
}
更彈性的建構式
class Sub extends Super {
private int x;
public Sub(int i) {
if (i == 0) throw new RuntimeException();
this.x = 1_000 / i; // 可以賦值
println("i=" + i);
// println("x=" + this.x); // 不可讀值
super(i); // 媽~~我在這!
}
}
1. 驗證傳?參數
2. 準備?∕?類別參數
3. 印出除錯訊息
4. 可賦值但不可讀取欄位
JEP 482:彈性建構式主體
● 呼叫?類別或??建構式前檢查初始化欄位
● 確保?類別欄位在?類別使?前已正確初始化
● 程式碼結構更清晰、易於閱讀和維護
● 若未設計好的話,可能會增加複雜性
● 需注意潛在的?險,例如呼叫未初始化的欄位
● 需確保相容既有程式,尤其是複雜的繼承關係
未命名變數
try (var _ : acquire()) { // try-with-resources
for (var _ : items) i++; // enhanced for loop
for (int j = 0, _ = init(); j < i; j++) // for loop
items.get(j);
var m = items.stream()
.collect(toMap(n -> n, _ -> 1L)); //lambda
} catch (Exception _) { // exception
println("Exception occurs!");
}
未命名模式 & 未命名模式變數
record Point(int x, int y) {}
record Circle(Point center, int radius) {}
record Rectangle(Point p1, Point p2) {}
if (o instanceof Circle(Point c, _)) { // int radius, 模式
println("Circle center: " + c);
} else if (o instanceof Rectangle(Point p1, _)) {//Point p2
println("Rectangle P1: " + p1);
} else if (o instanceof Point _) { // p, 模式變數
println("Point");
}
JEP 456:未命名變數和模式
● 簡化語法可減少冗餘程式碼,並易於閱讀和理解
● 專注於模式匹配,?不是變數名稱
● 與 switch、instanceof 的模式匹配無縫結合
● 如果舊程式中有 _ 命名的類別或欄位時會報錯
擴展基礎型別的模式匹配
record Box(double d) {}
if (b instanceof Box(int _)) {// 條件式轉型
println("Box integer " );// matches n.0
} else if (b instanceof Box(double _)) {
println("Box double"); // matches n.m, m!=0
}
DEMO
基礎型別的模式匹配
return switch(number) {
case byte _ -> 1;
case int _ -> 2;
// Error: this case label is dominated
// by a preceding case label
case short _ -> 3; // 注意支配權
case long _ -> 4;
};
JEP 455:基礎型別的模式匹配
● 加強模式匹配,適?更廣的候選基礎型別
record Box(double d) 可以?
instanceof Box(int i) 去判定是否能轉型成 int
● 擴展 instanceof 與基礎型別的模式匹配
if (o instanceof int i) ...
● 擴展 switch 處理基礎型別的模式匹配
case byte b -> ...
?件註釋選? HTML 的原因
● 1995 年選 HTML 是因為功能完整、標準,且當時
?常流?
● 現在已不流???寫 HTML
● 寫起來很繁瑣,閱讀不易
● 許多新的開發者已經不熟悉 HTML
換? Markdown 的好處
● 適合寫簡單?件、易於閱讀和轉換成 HTML
● 提供更簡單的形式撰寫?件註釋中的常?結構
● 能保留原有的?內和區塊標籤,例如
{@inheritDoc}、@param、@return
現有的 HTML JavaDoc
/**
* {@inheritDoc} Link to {@link String}.
* <p>
* Test items:
* <ul>
* <li> {@code hashCode}
* <li> {@link #equals(Object) equals}
* <li> <em>EM</em>
* </ul>
*
* @return a hash code value for this object.
* @see java.lang.System#identityHashCode
*/
新的 Markdown JavaDoc
/// {@inheritDoc} Link to [String].
///
/// Test items:
///
/// - `hashCode`
/// - [equals][#equals(Object)]
/// - _toString_
///
/// @return a hash code value for this object.
/// @see java.lang.System#identityHashCode
1./// 起始
2.[x]:連結
3.空??表?段落
4.– x:清單
5.`x`:等寬字
6._x_:強調字
7.@標籤不受影響
?援簡單的表格
/// | Latin | Greek |
/// |-------|-------|
/// | a | alpha |
/// | b | beta |
/// | c | gamma |
JEP 467:Markdown ?件註解
● 引? /// 作為 Markdown 的註釋開頭
● ?連結語法來連結類別、?法、欄位等
● ?表格語法(?)建?表格
● ? JavaDoc @ 標籤以保留現有功能
JEP 458:啟動多檔案的原始碼程式
● 執?多個原始碼檔案?無需事先編譯
● ?動編譯所需類別,並調?指定類別的 main ?法
● 無需顯式編譯和複雜設定,降低?檻提?效率
● 快速修改和測試,無需每次重新編譯整個專案
● 不適?於?型專案,尤其是專案結構和依賴管理
● 啟動器需即時編譯,可能會在啟動時有額外延遲
並?開發
提?執?效能,減少開發難度
提?執?效能,減少開發難度
1. JEP 473:串流聚集器 (2nd Prev)
2. JEP 480:結構化並?處理 (3rd Prev)
3. JEP 481:範圍值 (3rd Prev)
4. JEP 469:向量 API (8th Incubator)
Gatherer 介??法
● initializer():建?物件,在處理串流元素時可
維護內部狀態,例如暫存、計數、緩衝等
● integrator():從輸?串流接收新元素、更新內
部狀態、新增元素到下游串流、或終?處理
● combiner():並?處理時合併聚集器內部狀態
● finisher():沒有輸?元素時做最終處理,例如
拋出異常
內建 Gatherer 功能
● fold:多對?,消化元素並計算最終結果
● scan:?對?,消化元素並計算累積中間值
● mapConcurrent:?對?,對應新元素
● windowFixed:多對多,將元素依數量分組後傳遞
● windowSliding:同上,差異為滑動窗?
內建 Gatherer 使?場景
● fold:平均值、總和、計數、最?最?值
● scan:前綴和、累積乘積、費式數列
● mapConcurrent:下載、讀檔、複雜運算、圖?
● windowFixed:批次處理、緩衡區讀取
● windowSliding:移動平均、局部最?值
fold vs. scan
Stream.of(1, 2, 3, 4)
.gather(Gatherers.fold(()->0, (a,b)->a+b))
.toList(); // 總和: [10]
Stream.of(1, 2, 3, 4)
.gather(Gatherers.scan(()->0, (a,b)->a+b))
.toList(); // 前綴和: [1, 3, 6, 10]
延伸 Gatherer 範例
Stream.of(1, 2, 3, 4) //scan: [1, 3, 6, 10]
.gather(Gatherers.scan(() -> 0, (a, b) -> a + b))
.gather(Gatherers.windowFixed(2))
.map(w -> (w.get(0) + w.get(1)) / 2.0) // 需為偶數
.toList(); // 區間平均: [2.0, 8.0]
Stream.of(1, 2, 3, 4)
.gather(Gatherers.scan(() -> 0, (a, b) -> a + b))
.gather(Gatherers.windowSliding(2))
.map(w -> (w.get(0) + w.get(1)) / 2.0)
.toList(); // 移動平均: [2.0, 4.5, 8.0]
JEP 473:串流聚集器
● 引?中間操作 Gatherer 聚集器
● 聚集器去處理、轉換串流元素
● 可建??效並?的串流,實現幾乎任何中間操作
● Stream::collect(Collector) :終端操作
Stream::gather(Gatherer):中間操作
?結構化並?容易造成執?緒洩漏
Response handle(Request r) throws Exception {
Future<User> u = es.submit(() -> find(r)); //(1)
Future<Item> i = es.submit(() -> take(r)); //(2)
User user = u.get(); // (3)
Item item = i.get(); // (4)
return new Response(user, item);
}
1. find 失敗讓 (3) 拋異常時,take 執?緒仍會執?
2.handle 的執?緒中斷後 (1) 和 (2) 的執?緒仍會執?
3. 若 find 跑太久且 take 失敗,要很久 (4) 執?後知道
結構化並?程式碼
Response handle(Request r) {
try (var scope = new
StructuredTaskScope.ShutdownOnFailure()) {
Supplier<User> u = scope.fork(() -> find(r));
Supplier<Item> i = scope.fork(() -> take(r));
scope.join().throwIfFailed();
return new Response(u.get(), i.get());
} catch (Exception _) {
throw new RuntimeException();
}
}
JEP 480:結構化並?處理
● 提供結構化、可靠、可觀測的並?模型
● StructuredTaskScope 協調並??任務
○ fork:建?與啟動?任務,並返回結果
○ join:等待所有?任務完成,並處理異常
○ shutdown:取消未完成的?任務並防?分叉新任務
○ ?任務完成後?任務才完成,並集中處理異常
● 簡化錯誤處理、?動傳播取消、可觀測性
● ?任務繼承?任務的範圍值綁定,簡化資料共享
範圍值
private final static ScopedValue<Context> C
= ScopedValue.newInstance(); // INIT
Response serve(Request r) {// callWhere => SET
return ScopedValue.callWhere(C, // key
getContext(), // value
() -> handle(r)); // op
}
String getDbInfo(String k) {
return C.get().dbInfo(); // GET
}
JEP 481:範圍值
● 引? ScopedValue 作為共享資料的容器
○ runWhere(k, v, op)、callWhere(k, v, op):
綁定範圍值並執? op 操作
○ 在?命週期內,op 可透過 get 讀取範圍值
● ?執?緒可以共享?執?緒的範圍值綁定
JEP 469:向量 API
● 可建?、操作、訪問與計算向量計算的簡潔 API
● 能在?援向量指令的多個架構上實現平台獨?
● 在不完全?援的架構中能優雅地降級並完成操作
底層互動
改善調?機制,提?存取安全
改善調?機制,提?存取安全
1. JEP 454:外部函式與記憶體 API
2. JEP 471:棄? sun.misc.Unsafe 中的記憶體存取?法
3. JEP 423:G1 區域釘選
4. JEP 474:ZGC 預設啟動分代模式
5. JEP 466:類別檔 API (2nd Prev)
JEP 454:外部函式與記憶體 API
● 安全地分配、存取和釋放外部記憶體
● 提供機制呼叫原?函式
● 防?不正確的記憶體存取或函式呼叫?崩潰
● 對原?記憶體和函式有低階存取並維持抽象層
● 易?、簡潔、模組化的 API 更容易維護和擴展
● 與原?程式碼和記憶體的互動具有?定的複雜度
● 不熟悉原?程式設計概念的?會有學習曲線
JEP 471:棄??舊記憶體存取?法
● 宣告移除 sun.misc.unsafe ?於外部記憶體存取
的不安全?法,它們會導致安全漏洞或程式崩潰
● FFM API 能有效且安全地存取外部記憶體,因此棄
?不安全的記憶體存取?法
什麼是臨界區域 Critical Region?
● 原?程式碼要存取 JVM 資料時(像int[])可以
將資料複製到本地記憶體處理,但耗時耗空間
● 臨界區域允許 JNI 取得和釋放資料指標,例如
GetPrimitiveArrayCritical, ReleasePrimitiveArrayCritical
GetStringCritical, ReleaseStringCritical, ......
讓原?程式碼能直接操作 Java 物件以提升效能
● 為確保資料不被移動或回收,G1 選擇在臨界區域
內暫停 GC
JEP 423:G1 區域釘選
● 擴? G1 釘選功能到臨界區域的物件
● 在 GC 時不移動或回收被釘選的物件,但仍可處理
其他未釘選的區域
● 不需等待指標釋放,減少潛在停頓時間與延遲
● 因此在臨界區域期間內不需要禁?垃圾收集
JEP 474:ZGC 預設啟動分代模式
● 分代通常效能更佳:更頻繁地收集年輕代物件,減
少了垃圾收集的總時間
● 減少同時?援分代和未分代模式的維護?作
● ZGenerational 選項的預設值改為 true
● 棄? ZGenerational 選項,若使?則發出警告
JEP 466:類別檔 API
● 原因:類別 class 檔格式每六個?更新
● 需要標準 API 提?程式碼的可移植性和可維護性
● 易?、降低複雜性,並靈活滿?不同需求
● 以不可變物件來進?安全的元素存取和操作
● 提供建構器 builder ?成並輸出檔案
● 可轉換現有類別檔中的元素
What's Next in 24?
Only one so far
JEP 472 準備限制 JNI 使?
● 避免與原?程式碼之間未受控管的未定義?為和資
料交換
● 預設不允許與原?程式碼互動(JNI 與 FFM),
除?程式啟動時明確指定啟?
● 使? java --enable-native-access 選項啟?
JNI 與 FFM ?援
Review
Everything All at Once
Java 22 JEP Java 23 JEP
1 423 Region Pinning for G1
2 447 Statements before super(...) (Prev) 482 Flexible Constructor Bodies (2nd Prev)
3 454 Foreign Function & Memory API
4 456 Unnamed Variables & Patterns
5 457 Class-File API (Prev) 466 Class-File API (2nd Prev)
6 458 Launch Multi-file Source-code Programs
7 459 String Templates (2nd Prev) --
8 460 Vector API (7th Incubator) 469 Vector API (8th Incubator)
9 461 Stream Gatherers (Prev) 473 Stream Gatherers (2nd Prev)
10 462 Structured Concurrency (2nd Prev) 480 Structured Concurrency (3rd Prev)
11
463 Implicitly Declared Classes and
Instance Main Methods (2nd Prev)
477 Implicitly Declared Classes and
Instance Main Methods (3rd Prev)
12 464 Scoped Values (2nd Prev) 481 Scoped Values (3rd Prev)
13 467 Markdown Documentation Comments
14
455 Primitive Types in Patterns, instanceof,
and switch (Prev)
15
471 Deprecate the Memory-Access
Methods in sun.misc.Unsafe for Removal
16 474 ZGC: Generational Mode by Default
17 476 Module Import Declarations (Prev)
18 Java 24: 472 Prepare to Restrict the Use of JNI
Java 22 JEP Java 23 JEP
1 423 G1 區域釘選
2 447 super(...) 前的表達式 (Prev) 482 彈性建構式主體 (2nd Prev)
3 454 外部函式與記憶體 API
4 456 未命名變數和模式
5 457 類別檔 API (Prev) 466 類別檔 API (2nd Prev)
6 458 啟動多檔案的原始碼程式
7 459 字串模版 (2nd Prev) --
8 460 向量 API (7th Incubator) 469 向量 API (8th Incubator)
9 461 串流聚集器 (Prev) 473 串流聚集器 (2nd Prev)
10 462 結構化並?處理 (2nd Prev) 480 結構化並?處理 (3rd Prev)
11 463 隱式宣告類別和實例主?法 (2nd Prev) 477 隱式宣告類別和實例主?法 (3rd Prev)
12 464 範圍值 (2nd Prev) 481 範圍值 (3rd Prev)
13 467 Markdown ?件註解
14
455 模式、instanceof 與 switch 中的基礎型
別 (Prev)
15 471 棄? sun.misc.Unsafe 記憶體存取?法
16 474 ZGC:預設啟動分代模式
17 476 模組匯?宣告 (Prev)
18 Java 24: 472 準備限制 JNI 使?
Q&A

More Related Content

JCConf 2024 - Java 22 & 23 新功能介紹

  • 1. Java 22 & 23 新功能介紹 Joseph Kuo (CyberJos) VP of Technology @ NextDrive
  • 2. About Me ? '93 QBasic、'96 C/C++、'99 Java ? 資訊教育、雲端影?、電?商務、 資安防駭、???為、智慧物聯 ? JCConf、Oracle Groundbreakers、AWS Summit、 AWS Startup Day、物聯網年會、永續淨零論壇、… ? 軟體?程、後端技術、設計架構、雲端邊緣、 智慧物聯、永續能源、資安稽核、技術教學 ? 希望能?輩?玩技術寫程式到?
  • 3. Taiwan Java User Group ? FB:https://www.facebook.com/groups/twjug ? 官?網站:http://www.twjug.org/ ? LINE 社群「Java 程式語?討論區」
  • 4. Agenda ● 2024 State of Java Ecosystem ● New Features in 22 & 23 ● What's Next in 24?
  • 7. 2024 State of Java Ecosystem Published by New Relic
  • 8. 2023 State of Java Ecosystem ● 2020/03 New Relic 第一次報告發表 ● 2024/04 發表 2024 年度報告 ● 統計了上百萬個應用程式的回報資料 ● 報告資料僅包含了 2024 年向 New Relic 回報的應 用程式,不代表 Java 整體的使用情況 Source: https://newrelic.com/resources/report/2024-state-of-the-java-ecosystem
  • 13. New Features in 22 & 23 17 features in total
  • 16. 降低學習?檻,消除冗餘代碼 1. JEP 477:隱式宣告類別和實例 main ?法 (3rd Prev) 2. JEP 476:模組匯?宣告 (Prev) 3. JEP 482:彈性建構式主體 (2nd Prev) 4. JEP 456:未命名變數和模式 5. JEP 455:模式、instanceof 與 switch 的基礎型別 (Prev) 6. JEP 467:Markdown ?件註解 7. JEP 458:啟動多檔案的原始碼程式
  • 17. 開不了?的「安安你好」 // HelloWorld.java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } 1. 需學習 public 與繼承和套件存取 2. 需學習 static 與靜態和實例成員 3. 寫 class {} 但?不到(類別) 4. 傳 String[] 但沒?到(陣列、命令列) 5. 已沒?氣解釋 System.out.println …
  • 18. 實例 main ?法 // HelloWorld.java public class HelloWorld { void main() { System.out.println("Hello, World!"); } } 1. 主?法不需要 public 2. 主?法不需要 static 3. 不需要傳?String[]
  • 19. 隱式宣告類別 // HelloWorld.java <- 檔名即為類別名稱 void main() { System.out.println("Hello, World!"); } 1. 不需要 class {} 2. ?動建?隱式類別: final class HelloWorld extends Object
  • 20. ?動匯?新的 I/O ?法 // HelloWorld.java // import static java.io.IO.*; // 預設靜態匯入 void main() { println("Hello, World!"); } 1. void println(Object obj) 2. void print(Object obj) 3. String readln(String prompt)
  • 21. 使??式與限制 String hello() { return "Hello, "; } String world = "World!"; void main() { println(this.hello() + this.world); } 1. 未被 class {} 包覆的視為隱式類別 2. 外部類別無法呼叫其建構式與靜態成員 3. 只允許預設無參數建構式 4. 不能實作介? 5. 必須要有合法的 main ?法
  • 22. 更複雜的例? String hello() { return "Hello, "; } void main() { println(this.hello() + Test.get()); } class Test { // 內部類別 static String get() { String name = readln("Your name: "); // 從輸?讀值 return "" != name ? name : "World!"; } }
  • 23. 程式進?點順序 1. 非 private 的 static void main(String[] a) 2. 非 private 的 static void main() 3. 非 private 的 void main(String[] a) 4. 非 private 的 void main()
  • 24. DEMO
  • 25. JEP 477:隱式宣告類別和實例主?法 ● 實例或無參數的 main ?法 ● 沒有 class 檔名 {} 包覆的內容建?隱式類別 ● ?動 import static java.io.IO.* ● ?動 import module java.base ● 無法被其他類別引?或繼承 ● 不適?於?型專案
  • 26. 模組匯?宣告 import module java.base; // 模組匯? import static java.io.IO.*; class ModuleImport { void main() { var list = List.of("World!", "All!", ":)"); var n = new Random().nextInt(list.size()); println("Hello, " + list.get(n)); } }
  • 27. 模糊匯?的衝突解決 import module java.base; // java.util.Date import module java.sql; // java.sql.Date import java.sql.Date; // 單?型別匯? 1. 匯?多模組時會有匯?衝突 2. 需另外?型別匯?去指明
  • 28. JEP 476:模組匯?宣告 ● 匯?模組中的所有定義導出的型別 ● 不需學習類別的套件階層 ● 減少?量 import 語句 ● 不影響現有 import 語句?為 ● 會降低程式碼可讀性 ● 查找某類別的套件名稱時會有點?苦
  • 29. 早期在建構時想檢查參數 class Sub extends Super { public Sub(int i) { super(check(i)); // 只能透過靜態?法檢查 } static int check(int i) { if (i == 0) throw new RuntimeException(); return i; } }
  • 30. 更彈性的建構式 class Sub extends Super { private int x; public Sub(int i) { if (i == 0) throw new RuntimeException(); this.x = 1_000 / i; // 可以賦值 println("i=" + i); // println("x=" + this.x); // 不可讀值 super(i); // 媽~~我在這! } } 1. 驗證傳?參數 2. 準備?∕?類別參數 3. 印出除錯訊息 4. 可賦值但不可讀取欄位
  • 31. JEP 482:彈性建構式主體 ● 呼叫?類別或??建構式前檢查初始化欄位 ● 確保?類別欄位在?類別使?前已正確初始化 ● 程式碼結構更清晰、易於閱讀和維護 ● 若未設計好的話,可能會增加複雜性 ● 需注意潛在的?險,例如呼叫未初始化的欄位 ● 需確保相容既有程式,尤其是複雜的繼承關係
  • 32. 未命名變數 try (var _ : acquire()) { // try-with-resources for (var _ : items) i++; // enhanced for loop for (int j = 0, _ = init(); j < i; j++) // for loop items.get(j); var m = items.stream() .collect(toMap(n -> n, _ -> 1L)); //lambda } catch (Exception _) { // exception println("Exception occurs!"); }
  • 33. 未命名模式 & 未命名模式變數 record Point(int x, int y) {} record Circle(Point center, int radius) {} record Rectangle(Point p1, Point p2) {} if (o instanceof Circle(Point c, _)) { // int radius, 模式 println("Circle center: " + c); } else if (o instanceof Rectangle(Point p1, _)) {//Point p2 println("Rectangle P1: " + p1); } else if (o instanceof Point _) { // p, 模式變數 println("Point"); }
  • 34. JEP 456:未命名變數和模式 ● 簡化語法可減少冗餘程式碼,並易於閱讀和理解 ● 專注於模式匹配,?不是變數名稱 ● 與 switch、instanceof 的模式匹配無縫結合 ● 如果舊程式中有 _ 命名的類別或欄位時會報錯
  • 35. 擴展基礎型別的模式匹配 record Box(double d) {} if (b instanceof Box(int _)) {// 條件式轉型 println("Box integer " );// matches n.0 } else if (b instanceof Box(double _)) { println("Box double"); // matches n.m, m!=0 }
  • 36. DEMO
  • 37. 基礎型別的模式匹配 return switch(number) { case byte _ -> 1; case int _ -> 2; // Error: this case label is dominated // by a preceding case label case short _ -> 3; // 注意支配權 case long _ -> 4; };
  • 38. JEP 455:基礎型別的模式匹配 ● 加強模式匹配,適?更廣的候選基礎型別 record Box(double d) 可以? instanceof Box(int i) 去判定是否能轉型成 int ● 擴展 instanceof 與基礎型別的模式匹配 if (o instanceof int i) ... ● 擴展 switch 處理基礎型別的模式匹配 case byte b -> ...
  • 39. ?件註釋選? HTML 的原因 ● 1995 年選 HTML 是因為功能完整、標準,且當時 ?常流? ● 現在已不流???寫 HTML ● 寫起來很繁瑣,閱讀不易 ● 許多新的開發者已經不熟悉 HTML
  • 40. 換? Markdown 的好處 ● 適合寫簡單?件、易於閱讀和轉換成 HTML ● 提供更簡單的形式撰寫?件註釋中的常?結構 ● 能保留原有的?內和區塊標籤,例如 {@inheritDoc}、@param、@return
  • 41. 現有的 HTML JavaDoc /** * {@inheritDoc} Link to {@link String}. * <p> * Test items: * <ul> * <li> {@code hashCode} * <li> {@link #equals(Object) equals} * <li> <em>EM</em> * </ul> * * @return a hash code value for this object. * @see java.lang.System#identityHashCode */
  • 42. 新的 Markdown JavaDoc /// {@inheritDoc} Link to [String]. /// /// Test items: /// /// - `hashCode` /// - [equals][#equals(Object)] /// - _toString_ /// /// @return a hash code value for this object. /// @see java.lang.System#identityHashCode 1./// 起始 2.[x]:連結 3.空??表?段落 4.– x:清單 5.`x`:等寬字 6._x_:強調字 7.@標籤不受影響
  • 43. ?援簡單的表格 /// | Latin | Greek | /// |-------|-------| /// | a | alpha | /// | b | beta | /// | c | gamma |
  • 44. JEP 467:Markdown ?件註解 ● 引? /// 作為 Markdown 的註釋開頭 ● ?連結語法來連結類別、?法、欄位等 ● ?表格語法(?)建?表格 ● ? JavaDoc @ 標籤以保留現有功能
  • 45. JEP 458:啟動多檔案的原始碼程式 ● 執?多個原始碼檔案?無需事先編譯 ● ?動編譯所需類別,並調?指定類別的 main ?法 ● 無需顯式編譯和複雜設定,降低?檻提?效率 ● 快速修改和測試,無需每次重新編譯整個專案 ● 不適?於?型專案,尤其是專案結構和依賴管理 ● 啟動器需即時編譯,可能會在啟動時有額外延遲
  • 47. 提?執?效能,減少開發難度 1. JEP 473:串流聚集器 (2nd Prev) 2. JEP 480:結構化並?處理 (3rd Prev) 3. JEP 481:範圍值 (3rd Prev) 4. JEP 469:向量 API (8th Incubator)
  • 48. Gatherer 介??法 ● initializer():建?物件,在處理串流元素時可 維護內部狀態,例如暫存、計數、緩衝等 ● integrator():從輸?串流接收新元素、更新內 部狀態、新增元素到下游串流、或終?處理 ● combiner():並?處理時合併聚集器內部狀態 ● finisher():沒有輸?元素時做最終處理,例如 拋出異常
  • 49. 內建 Gatherer 功能 ● fold:多對?,消化元素並計算最終結果 ● scan:?對?,消化元素並計算累積中間值 ● mapConcurrent:?對?,對應新元素 ● windowFixed:多對多,將元素依數量分組後傳遞 ● windowSliding:同上,差異為滑動窗?
  • 50. 內建 Gatherer 使?場景 ● fold:平均值、總和、計數、最?最?值 ● scan:前綴和、累積乘積、費式數列 ● mapConcurrent:下載、讀檔、複雜運算、圖? ● windowFixed:批次處理、緩衡區讀取 ● windowSliding:移動平均、局部最?值
  • 51. fold vs. scan Stream.of(1, 2, 3, 4) .gather(Gatherers.fold(()->0, (a,b)->a+b)) .toList(); // 總和: [10] Stream.of(1, 2, 3, 4) .gather(Gatherers.scan(()->0, (a,b)->a+b)) .toList(); // 前綴和: [1, 3, 6, 10]
  • 52. 延伸 Gatherer 範例 Stream.of(1, 2, 3, 4) //scan: [1, 3, 6, 10] .gather(Gatherers.scan(() -> 0, (a, b) -> a + b)) .gather(Gatherers.windowFixed(2)) .map(w -> (w.get(0) + w.get(1)) / 2.0) // 需為偶數 .toList(); // 區間平均: [2.0, 8.0] Stream.of(1, 2, 3, 4) .gather(Gatherers.scan(() -> 0, (a, b) -> a + b)) .gather(Gatherers.windowSliding(2)) .map(w -> (w.get(0) + w.get(1)) / 2.0) .toList(); // 移動平均: [2.0, 4.5, 8.0]
  • 53. JEP 473:串流聚集器 ● 引?中間操作 Gatherer 聚集器 ● 聚集器去處理、轉換串流元素 ● 可建??效並?的串流,實現幾乎任何中間操作 ● Stream::collect(Collector) :終端操作 Stream::gather(Gatherer):中間操作
  • 54. ?結構化並?容易造成執?緒洩漏 Response handle(Request r) throws Exception { Future<User> u = es.submit(() -> find(r)); //(1) Future<Item> i = es.submit(() -> take(r)); //(2) User user = u.get(); // (3) Item item = i.get(); // (4) return new Response(user, item); } 1. find 失敗讓 (3) 拋異常時,take 執?緒仍會執? 2.handle 的執?緒中斷後 (1) 和 (2) 的執?緒仍會執? 3. 若 find 跑太久且 take 失敗,要很久 (4) 執?後知道
  • 55. 結構化並?程式碼 Response handle(Request r) { try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Supplier<User> u = scope.fork(() -> find(r)); Supplier<Item> i = scope.fork(() -> take(r)); scope.join().throwIfFailed(); return new Response(u.get(), i.get()); } catch (Exception _) { throw new RuntimeException(); } }
  • 56. JEP 480:結構化並?處理 ● 提供結構化、可靠、可觀測的並?模型 ● StructuredTaskScope 協調並??任務 ○ fork:建?與啟動?任務,並返回結果 ○ join:等待所有?任務完成,並處理異常 ○ shutdown:取消未完成的?任務並防?分叉新任務 ○ ?任務完成後?任務才完成,並集中處理異常 ● 簡化錯誤處理、?動傳播取消、可觀測性 ● ?任務繼承?任務的範圍值綁定,簡化資料共享
  • 57. 範圍值 private final static ScopedValue<Context> C = ScopedValue.newInstance(); // INIT Response serve(Request r) {// callWhere => SET return ScopedValue.callWhere(C, // key getContext(), // value () -> handle(r)); // op } String getDbInfo(String k) { return C.get().dbInfo(); // GET }
  • 58. JEP 481:範圍值 ● 引? ScopedValue 作為共享資料的容器 ○ runWhere(k, v, op)、callWhere(k, v, op): 綁定範圍值並執? op 操作 ○ 在?命週期內,op 可透過 get 讀取範圍值 ● ?執?緒可以共享?執?緒的範圍值綁定
  • 59. JEP 469:向量 API ● 可建?、操作、訪問與計算向量計算的簡潔 API ● 能在?援向量指令的多個架構上實現平台獨? ● 在不完全?援的架構中能優雅地降級並完成操作
  • 61. 改善調?機制,提?存取安全 1. JEP 454:外部函式與記憶體 API 2. JEP 471:棄? sun.misc.Unsafe 中的記憶體存取?法 3. JEP 423:G1 區域釘選 4. JEP 474:ZGC 預設啟動分代模式 5. JEP 466:類別檔 API (2nd Prev)
  • 62. JEP 454:外部函式與記憶體 API ● 安全地分配、存取和釋放外部記憶體 ● 提供機制呼叫原?函式 ● 防?不正確的記憶體存取或函式呼叫?崩潰 ● 對原?記憶體和函式有低階存取並維持抽象層 ● 易?、簡潔、模組化的 API 更容易維護和擴展 ● 與原?程式碼和記憶體的互動具有?定的複雜度 ● 不熟悉原?程式設計概念的?會有學習曲線
  • 63. JEP 471:棄??舊記憶體存取?法 ● 宣告移除 sun.misc.unsafe ?於外部記憶體存取 的不安全?法,它們會導致安全漏洞或程式崩潰 ● FFM API 能有效且安全地存取外部記憶體,因此棄 ?不安全的記憶體存取?法
  • 64. 什麼是臨界區域 Critical Region? ● 原?程式碼要存取 JVM 資料時(像int[])可以 將資料複製到本地記憶體處理,但耗時耗空間 ● 臨界區域允許 JNI 取得和釋放資料指標,例如 GetPrimitiveArrayCritical, ReleasePrimitiveArrayCritical GetStringCritical, ReleaseStringCritical, ...... 讓原?程式碼能直接操作 Java 物件以提升效能 ● 為確保資料不被移動或回收,G1 選擇在臨界區域 內暫停 GC
  • 65. JEP 423:G1 區域釘選 ● 擴? G1 釘選功能到臨界區域的物件 ● 在 GC 時不移動或回收被釘選的物件,但仍可處理 其他未釘選的區域 ● 不需等待指標釋放,減少潛在停頓時間與延遲 ● 因此在臨界區域期間內不需要禁?垃圾收集
  • 66. JEP 474:ZGC 預設啟動分代模式 ● 分代通常效能更佳:更頻繁地收集年輕代物件,減 少了垃圾收集的總時間 ● 減少同時?援分代和未分代模式的維護?作 ● ZGenerational 選項的預設值改為 true ● 棄? ZGenerational 選項,若使?則發出警告
  • 67. JEP 466:類別檔 API ● 原因:類別 class 檔格式每六個?更新 ● 需要標準 API 提?程式碼的可移植性和可維護性 ● 易?、降低複雜性,並靈活滿?不同需求 ● 以不可變物件來進?安全的元素存取和操作 ● 提供建構器 builder ?成並輸出檔案 ● 可轉換現有類別檔中的元素
  • 68. What's Next in 24? Only one so far
  • 69. JEP 472 準備限制 JNI 使? ● 避免與原?程式碼之間未受控管的未定義?為和資 料交換 ● 預設不允許與原?程式碼互動(JNI 與 FFM), 除?程式啟動時明確指定啟? ● 使? java --enable-native-access 選項啟? JNI 與 FFM ?援
  • 71. Java 22 JEP Java 23 JEP 1 423 Region Pinning for G1 2 447 Statements before super(...) (Prev) 482 Flexible Constructor Bodies (2nd Prev) 3 454 Foreign Function & Memory API 4 456 Unnamed Variables & Patterns 5 457 Class-File API (Prev) 466 Class-File API (2nd Prev) 6 458 Launch Multi-file Source-code Programs 7 459 String Templates (2nd Prev) -- 8 460 Vector API (7th Incubator) 469 Vector API (8th Incubator) 9 461 Stream Gatherers (Prev) 473 Stream Gatherers (2nd Prev) 10 462 Structured Concurrency (2nd Prev) 480 Structured Concurrency (3rd Prev) 11 463 Implicitly Declared Classes and Instance Main Methods (2nd Prev) 477 Implicitly Declared Classes and Instance Main Methods (3rd Prev) 12 464 Scoped Values (2nd Prev) 481 Scoped Values (3rd Prev) 13 467 Markdown Documentation Comments 14 455 Primitive Types in Patterns, instanceof, and switch (Prev) 15 471 Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal 16 474 ZGC: Generational Mode by Default 17 476 Module Import Declarations (Prev) 18 Java 24: 472 Prepare to Restrict the Use of JNI
  • 72. Java 22 JEP Java 23 JEP 1 423 G1 區域釘選 2 447 super(...) 前的表達式 (Prev) 482 彈性建構式主體 (2nd Prev) 3 454 外部函式與記憶體 API 4 456 未命名變數和模式 5 457 類別檔 API (Prev) 466 類別檔 API (2nd Prev) 6 458 啟動多檔案的原始碼程式 7 459 字串模版 (2nd Prev) -- 8 460 向量 API (7th Incubator) 469 向量 API (8th Incubator) 9 461 串流聚集器 (Prev) 473 串流聚集器 (2nd Prev) 10 462 結構化並?處理 (2nd Prev) 480 結構化並?處理 (3rd Prev) 11 463 隱式宣告類別和實例主?法 (2nd Prev) 477 隱式宣告類別和實例主?法 (3rd Prev) 12 464 範圍值 (2nd Prev) 481 範圍值 (3rd Prev) 13 467 Markdown ?件註解 14 455 模式、instanceof 與 switch 中的基礎型 別 (Prev) 15 471 棄? sun.misc.Unsafe 記憶體存取?法 16 474 ZGC:預設啟動分代模式 17 476 模組匯?宣告 (Prev) 18 Java 24: 472 準備限制 JNI 使?
  • 73. Q&A