Java 語言自 1995 年誕生以來,經歷了多個里程碑版本的演進。JDK 5 引入的語法糖奠定了現代 Java 開發基礎,JDK 7 完善了語法表達力,JDK 8 則帶來了函數式編程的範式革命。本文系統梳理 JDK 5-8 核心特性,對比演進脈絡,助你構建完整的版本知識體系。
代號 Tiger,被公認為語法層面變化最大的版本,引入 5 大核心特性:
// 編譯時類型檢查,運行時擦除為原始類型
List<String> list = new ArrayList<>();
list.add("hello");
// list.add(123); // 編譯報錯
// 泛型方法
public <T> void print(T t) { System.out.println(t); }
// 通配符與邊界
List<? extends Number> nums = new ArrayList<Integer>();
List<? super Integer> consumers = new ArrayList<Number>();
核心價值:將運行時 ClassCastException 前移至編譯期,消除強制轉型,API 文檔自文檔化。
for (String s : list) { ... }
for (Map.Entry<K,V> e : map.entrySet()) { ... }
要求實現 Iterable 接口,底層調用 iterator(),語法糖編譯為迭代器模式。
Integer i = 10; // 裝箱:Integer.valueOf(10)
int n = i; // 拆箱:i.intValue()
List<Integer> list = Arrays.asList(1,2,3); // 基本類型直接進集合
陷阱:Integer 緩存範圍 [-128, 127],超出範圍 new Integer() 不同對象,== 比較失效,請用 equals()。
public enum Season {
SPRING("春"), SUMMER("夏"), AUTUMN("秋"), WINTER("冬");
private final String cnName;
Season(String cnName) { this.cnName = cnName; }
public String getCnName() { return cnName; }
}
// 使用
Season s = Season.SPRING;
switch (s) { case SPRING: ... }
枚舉實質是 final class extends Enum,支援字段、方法、實現接口,可作為單例模式最佳實踐。
public void printAll(String... args) {
for (String s : args) System.out.println(s);
}
printAll("a", "b", "c");
printAll(new String[]{"x", "y"}); // 也可傳數組
本質是語法糖,編譯時封裝為數組,只能出現在參數列表最後。
import static java.lang.Math.*;
import static java.util.Collections.*;
sin(PI/2); emptyList();
慎用,過度使用降低代碼可讀性,難以追溯方法來源。
ReentrantLock、ReadWriteLock、ConditionExecutorService、ThreadPoolExecutor、ScheduledExecutorServiceConcurrentHashMap、CopyOnWriteArrayList、BlockingQueue 族系CountDownLatch、CyclicBarrier、Semaphore、ExchangerAtomicInteger、AtomicReference、LongAdder (JDK8)代號 Mustang,側重工程化工具鏈與企業級整合:
| 特性 | 核心類/API | 應用場景 |
|---|---|---|
| Desktop / SystemTray | java.awt.Desktop, SystemTray | 桌面整合:打開瀏覽器、郵件客戶端、系統托盤圖標 |
| JAXB 2.0 | javax.xml.bind.* | 對象⇄XML 雙向綁定,註解驅動,替代 DOM/SAX |
| StAX | javax.xml.stream.* | 拉式解析 XML,流式處理大文件,性能優於 DOM |
| Compiler API | javax.tools.JavaCompiler | 動態編譯 Java 源碼,支援 JSP 熱部署、代碼生成器 |
| 輕量級 HTTP Server | com.sun.net.httpserver.HttpServer | 嵌入式測試服務、Mock Server、微服務網關原型 |
| Pluggable Annotation Processing | javax.annotation.processing.* | 編譯期註解處理,代碼生成、檢查、Lombok/MapStruct 原理 |
| Console 類 | java.io.Console | 交互式命令行密碼讀取、格式化輸出 |
| 腳本引擎 (JSR 223) | javax.script.* | 運行 JavaScript/Groovy/Ruby/Scala 腳本,規則引擎、動態配置 |
| Common Annotations | javax.annotation.* | @Resource/@PostConstruct/@PreDestroy 等標準化註解 |
代號 Dolphin,Project Coin 小語言變更 + NIO.2 重磅升級:
// 1. 二進制字面量
int mask = 0b1010_1100_1111_0000;
// 2. 數值字面量下劃線分隔
long creditCard = 1234_5678_9012_3456L;
double pi = 3.14159_26535_89793;
// 3. Switch 支援 String
String level = "ERROR";
switch (level) {
case "DEBUG": log.debug(...); break;
case "ERROR": log.error(...); break;
default: log.info(...);
}
// 4. Try-with-resources (ARM) —— 自動資源管理
try (InputStream in = new FileInputStream("a.txt");
OutputStream out = new FileOutputStream("b.txt")) {
in.transferTo(out); // JDK 9 新增
} // 自動調用 close()
// 5. 多異常捕獲
try { ... }
catch (IOException | SQLException e) { // 隱含 final
logger.error(e);
}
// 6. 鑽石操作符 <> —— 類型推斷
Map<String, List<Integer>> map = new HashMap<>(); // 右側省略泛型
// 7. 簡化可變參數方法調用 (Heap Pollution 警告抑制)
@SafeVarargs
public void process(List<String>... lists) { ... }
Path path = Paths.get("/data", "logs", "app.log");
// 文件屬性
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
attrs.creationTime(); attrs.size(); attrs.isDirectory();
// 流式操作 (自動關閉)
try (Stream<Path> stream = Files.walk(Paths.get("/data"))) {
stream.filter(p -> p.toString().endsWith(".log"))
.forEach(System.out::println);
}
// 高效複製/移動/刪除
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES);
Files.move(src, dest, StandardCopyOption.ATOMIC_MOVE);
Files.deleteIfExists(path);
// 文件監聽
WatchService watcher = FileSystems.getDefault().newWatchService();
path.getParent().register(watcher, ENTRY_CREATE, ENTRY_MODIFY, ENTRY_DELETE);
requireNonNull()、equals(a,b)、hashCode(...)、toString(obj)Closeable,支援拋出異常,配合 try-with-resourcesRecursiveTask、RecursiveAction代號 Spider,Java 歷史上最大版本變更,核心三駕馬車:
// 函數式接口:單一抽象方法 (SAM)
@FunctionalInterface
interface Converter<F, T> { T convert(F from); }
// Lambda 實現
Converter<String, Integer> c = s -> Integer.parseInt(s);
Converter<String, Integer> c2 = Integer::parseInt; // 方法引用
// 集合操作
list.forEach(System.out::println);
list.removeIf(s -> s.isEmpty());
list.sort(Comparator.comparing(String::length));
List<String> result = list.stream()
.filter(s -> s.length() > 3)
.map(String::toUpperCase)
.distinct()
.sorted()
.limit(10)
.collect(Collectors.toList());
// 並行流 (ForkJoinPool.commonPool)
long count = list.parallelStream().filter(s -> s.startsWith("A")).count();
Optional<User> opt = Optional.ofNullable(userService.findById(id));
opt.ifPresent(u -> System.out.println(u.getName()));
User u = opt.orElseGet(() -> new User("guest"));
opt.orElseThrow(() -> new BusinessException("用戶不存在"));
LocalDate date = LocalDate.now();
LocalDateTime dt = LocalDateTime.of(2024, 1, 1, 12, 0);
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
Duration d = Duration.between(start, end);
Period p = Period.between(LocalDate.now(), LocalDate.of(2025, 1, 1));
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
interface Logger {
void log(String msg);
default void info(String msg) { log("[INFO] " + msg); } // 默認實現
static Logger getLogger() { return System.out::println; } // 靜態方法
}
@Schedule(dayOfWeek = "Mon")
@Schedule(dayOfWeek = "Fri") // 同一註解多次使用
public void cleanup() { ... }
@NotNull String name; // 類型註解,配合檢查框架
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello from JS');");
Base64.Encoder encoder = Base64.getEncoder();
Base64.Decoder decoder = Base64.getDecoder();
String encoded = encoder.encodeToString("Hello".getBytes());
| 維度 | JDK 5 | JDK 6 | JDK 7 | JDK 8 |
|---|---|---|---|---|
| 核心主題 | 語法糖與元編程 | 工具鏈與企業整合 | 語法精煉與 NIO.2 | 函數式編程革命 |
| 集合框架 | 泛型、Queue | — | — | Stream、默認方法 |
| 並發 | JUC 全家桶 | — | Fork/Join、TransferQueue | LongAdder、CompletableFuture、StampedLock |
| IO/NIO | — | — | NIO.2 (Path/Files/WatchService) | Stream IO、Base64 |
| 日期時間 | — | — | — | JSR 310 (java.time.*) |
| 模塊化 | — | — | — | — (JDK 9 Jigsaw) |
-source 8 -target 8,再逐步引入 Lambda/StreamDate/Calendar/SimpleDateFormat(非線程安全)release 參數確保交叉編譯正確性Java 的每個大版本都在解決前一版本的痛點:JDK 5 解決類型安全與樣板代碼,JDK 6 強化工程化基礎設施,JDK 7 改善語法表達與文件操作,JDK 8 引入函數式範式應對多核時代。理解演進脈絡,才能在技術選型與代碼審查中做出更專業的判斷。