Java 8 (2014/03) 是 Java 史上最大版本升級,引入函數式程式設計、Stream API、新時間日期庫等革命性特性。本文精選 10 大核心特性深度解析。
核心語法:(parameters) -> expression 或 (parameters) -> { statements; }
// 無參無回傳
() -> System.out.println("Hello")
// 有參有回傳
(String s) -> s.length()
s -> s.length() // 型別推導省略括號
// 多行語句
(int a, int b) -> {
int sum = a + b;
return sum;
}
函數式介面:僅有一個抽象方法的介面,可隱式轉換為 Lambda。標註 @FunctionalInterface 可編譯期檢查。常用內建:Predicate<T>、Function<T,R>、Consumer<T>、Supplier<T>。
Stream ≠ 集合,是**資料流管道**,支援鏈式操作:
List<String> list = Arrays.asList("a", "b", "c", "d");
list.stream()
.filter(s -> s.compareTo("b") > 0) // 過濾
.map(String::toUpperCase) // 映射
.sorted() // 排序
.forEach(System.out::println); // 終端操作
filter/map/sorted/distinct/limit/skip — 惰性求值,回傳新 StreamforEach/collect/reduce/count/findFirst — 觸發實際計算parallelStream() 自動多核並行,無序場景效能提升顯著容器物件,可能包含值也可能為空,強制呼叫端處理缺值情況:
Optional<User> opt = userRepository.findById(id);
opt.ifPresent(u -> System.out.println(u.getName())); // 有值才執行
User user = opt.orElse(new User("Guest")); // 缺值預設
User user = opt.orElseThrow(() -> new NotFoundException()); // 缺值拋異常
設計意圖:API 層面明確語義,而非文檔說明。避免 if (obj != null) 散落各處。
public interface Logger {
void log(String msg);
default void info(String msg) { log("[INFO] " + msg); } // 有實作
default void warn(String msg) { log("[WARN] " + msg); }
}
既有實作類**無需修改**即繼承新功能。解決介面擴充「爆炸性修改」痛點。但引入菱形繼承衝突需顯式解決。
徹底解決舊 Date/Calendar 痛點:不可變、執行緒安全、領域驅動設計:
| 類別 | 用途 | 範例 |
|---|---|---|
| LocalDate | 純日期 | LocalDate.now()、LocalDate.of(2024, 1, 1) |
| LocalTime | 純時間 | LocalTime.now()、LocalTime.of(13, 30) |
| LocalDateTime | 日期時間 | LocalDateTime.now() |
| ZonedDateTime | 帶時區 | ZonedDateTime.now(ZoneId.of("Asia/Taipei")) |
| Instant | 時間戳 | Instant.now()、Duration.between() |
| Period/Duration | 日期/時間間隔 | Period.between(d1, d2)、Duration.between(t1, t2) |
// 格式化/解析
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime.parse("2024-01-01 12:00", fmt);
ldt.format(fmt);
// 舊 Date 互轉
Date date = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
| 類型 | 語法 | 範例 | 等價 Lambda |
|---|---|---|---|
| 靜態方法 | Class::staticMethod | Integer::parseInt | s -> Integer.parseInt(s) |
| 實例方法 | obj::instanceMethod | System.out::println | x -> System.out.println(x) |
| 任意物件實例方法 | Class::instanceMethod | String::toUpperCase | s -> s.toUpperCase() |
| 建構子 | Class::new | ArrayList::new | () -> new ArrayList() |
@Repeatable:同一註解可在同一位置多次使用@Target(ElementType.TYPE_USE):註解可用於泛型型別參數、強轉、new、implements 等任意型別使用處,強化靜態分析工具 (如 Checker Framework)Java 8 內建 JS 引擎,jjs 指令執行 JS 檔。注意:Java 11 標記棄用,Java 15 移除,現代專案建議用 GraalVM Polyglot API。
Base64.Encoder encoder = Base64.getEncoder();
String encoded = encoder.encodeToString("Hello".getBytes());
Base64.Decoder decoder = Base64.getDecoder();
String decoded = new String(decoder.decode(encoded));
標準、URL-safe、MIME 三種變體,無需第三方庫。
Arrays.parallelSort():多核並行排序,大陣列效能大幅提升Math.addExact()、multiplyExact() 等:溢位檢查拋 ArithmeticException,替代隱性溢位LongAdder、DoubleAdder:高併發計數器,優於 AtomicLong (分段累加減少 CAS 競爭)StampedLock:樂觀讀鎖,讀多寫少場景效能優於 ReadWriteLockfor-each 仍可保留Optional 僅用於回傳值,避免用於欄位/參數