《Java 高级编程》目录
这一页是全书的总入口。它列出 9 章 27 节,也给出三条可以照着走的阅读路径。如果你不确定从哪里开始,先读下面的「这本书解决什么问题」,再对照「三条学习路径」选一条;如果你已经有明确目标,直接跳到「分部分章节」按编号定位。
全书结构是:前置 3 篇 + 正文 9 章 27 节 + 附录 4 篇,共 34 篇。正文按能力层次分为四个部分,每一部分对应 libraryd 的一类改造。
这本书解决什么问题
卷二结束时,libraryd 能启动、能借书、能打镜像。但很多行为你只是「会用」,没有「知道为什么」:
- 为什么
Repository要写成Repository<T, ID>,而不是给每张表写一个接口? @Transactional为什么在类内部自调用时失效?Class.forName和ClassLoader.loadClass有什么区别?volatile保证了什么,又没保证什么?- 虚拟线程能开一百万个,为什么连接池还是只能开十个?
switch里加一个case,编译器怎么知道你有没有漏?
这些问题不影响第一个版本上线,但会在第二次、第三次改造时反复出现。《Java 高级编程》只做一件事:把 Java 语言和标准库的机制讲清楚,并把它们放回 libraryd 的真实代码里。
具体拆开,是四个层次:
- 类型系统:把运行时错误提前到编译期。泛型、型变、擦除、sealed、record 模式、穷尽
switch。 - 运行时:反射、注解、动态代理、类加载、字节码、Instrumentation。理解框架的地基。
- 并发:JMM、原子类、锁、JUC、虚拟线程、结构化并发。知道每条规则在什么条件下成立。
- 平台与性能:JPMS、FFM、JMH、JFR。处理 Java 与外部世界的边界,以及「怎么知道改动有效」。
读者画像与前置知识
这本书适合三类读者:
| 读者 | 起点 | 建议入口 |
|---|---|---|
| 业务开发两三年 | 会用集合、Stream、Spring 注解,但排障靠搜索 | 第 1 章顺序读,重点第 4、6、9 章 |
| 其他语言转 Java | 知道泛型、协程、模块,但不确定 Java 的对应物 | 第 1、6、7、8 章,对照自己的语言 |
| 技术选型 / 面试准备 | 需要把零散知识点连成链路 | 先读目录与附录 C,再按主题跳读 |
前置知识:Java 基本语法、类与接口、异常、集合、Stream、Lambda;Thread 与 ExecutorService 的粗略用法;Maven 基本命令。不要求读过卷二,但例子会引用 Book、Member、Loan、ErrorCode、LibraryException,每章第一次出现时会简要重复。
九章结构一览
| 部分 | 章 | 主题 | 三节各讲什么 |
|---|---|---|---|
| 一、类型 | 1 | 类型系统进阶 | 泛型边界 / 型变与通配符 / 擦除与类型令牌 |
| 2 | 反射、注解与动态代理 | 反射核心 / 注解元数据 / 动态代理 | |
| 3 | 类加载、字节码与 Instrumentation | 类加载器 / 字节码 / Java Agent | |
| 二、并发 | 4 | JMM 与并发原语 | 可见性 / 原子类 / 锁与条件队列 |
| 5 | JUC 与并发容器 | 并发容器 / 阻塞队列 / 同步器 | |
| 6 | 虚拟线程与结构化并发 | 虚拟线程 / 结构化并发 / 落地陷阱 | |
| 三、语言与平台 | 7 | 现代语法与模式匹配 | record 模式 / sealed switch / 边界 |
| 8 | JPMS、FFM 与原生互操作 | 模块化 / FFM / 原生边界 | |
| 四、性能 | 9 | 性能工程 | JMH / JFR / 优化决策 |
三条学习路径
路径一:机制补课(约三周)
按第 1–9 章顺序读,每章先读前两节建立机制,再读第三节看落地。适合想把「听说过」变成「讲得清」的读者。
- 第 1–3 章:每天一章,重点是把代码真正编译运行一次。
- 第 4–6 章:并发部分不要只读,至少复现一次可见性实验、一次虚拟线程对比。
- 第 7–9 章:模式匹配与 JPMS/FFM 可以快读,性能章要动手跑 JMH。
路径二:改造 libraryd(约两周)
从第 1 章的 Repository<T, ID> 开始,跟着每节的「在 libraryd 里落地」改代码。第 3 章的插件加载器、第 6 章的虚拟线程聚合、第 8 章的模块化与 FFM,都是可以直接运行的改造。
适合已经有卷二代码、想通过改一个真实项目来理解机制的读者。
路径三:排障与速查(按需)
先看目录里的小节标题,再跳到对应章节。高频入口:
| 问题 | 章节 |
|---|---|
ClassNotFoundException / NoSuchMethodError | 3.1 类加载器 |
@Transactional 不生效 | 2.3 动态代理 |
| 线程间数据不可见 | 4.1 JMM 可见性 |
| 虚拟线程没有更快 | 6.1 虚拟线程原理 |
| 微基准结果不可信 | 9.1 JMH |
| 线上 CPU 高但不知道在哪 | 9.2 JFR |
分部分章节
前置与附录
| 节 | 文章 | 核心内容 |
|---|---|---|
| — | 序 | 为什么在能跑的服务之后还要讲语言机制、四个层次、与卷四的分工 |
| — | 前言 | 读者对象、环境清单与真实版本输出、代码约定、三种验证层次 |
| 附 A | 附录 A 并发 API 速查 | 原子类、锁、容器、队列、同步器、虚拟线程的场景与误用 |
| 附 B | 附录 B 反射与代理模板 | 注解、InvocationHandler、代理工厂、record 反射与模块开放 |
| 附 C | 附录 C 版本特性矩阵 | JDK 8/11/17/21/25 的语言与 API 变化、正式/预览状态 |
| 附 D | 附录 D 诊断命令清单 | jps、jcmd、jstack、jfr、javap、jdeps、jlink 的用法 |
第一部分:类型系统(第 1–3 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 1.1 | 1.1 泛型边界 | 从 BookRepository 抽到 Repository<T, ID>、有界类型参数、Page<T> |
| 1.2 | 1.2 型变与通配符 | PECS、? extends / ? super、生产者与消费者在查询 API 里的位置 |
| 1.3 | 1.3 擦除与类型令牌 | 擦除规则、桥方法、TypeReference、泛型数组为什么不能直接创建 |
| 2.1 | 2.1 反射核心 | Class、Method、Constructor、setAccessible、模块开放 |
| 2.2 | 2.2 注解与运行时元数据 | @Retention、@Target、@Audit、@Retry、注解处理器与运行时读取 |
| 2.3 | 2.3 动态代理 | JDK 动态代理、InvocationHandler、事务与重试的织入、自调用为何失效 |
| 3.1 | 3.1 类加载器与双亲委派 | 平台/应用加载器、双亲委派、PluginClassLoader 与 ServiceLoader |
| 3.2 | 3.2 字节码入门 | javap -c -p -v、常量池、方法调用指令、ASM 与 Byte Buddy 的选择 |
| 3.3 | 3.3 Instrumentation 与 Java Agent | premain、ClassFileTransformer、-javaagent、libraryd-agent 计时 |
第二部分:并发(第 4–6 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 4.1 | 4.1 可见性与重排序 | happens-before、volatile 的语义、DCL 与安全发布 |
| 4.2 | 4.2 原子类与 CAS | AtomicLong、LongAdder、ABA、VarHandle 与 LoanCounters |
| 4.3 | 4.3 锁与条件队列 | synchronized、ReentrantLock、Condition、AQS 的基本结构 |
| 5.1 | 5.1 并发容器 | ConcurrentHashMap、CopyOnWriteArrayList、弱一致迭代器 |
| 5.2 | 5.2 阻塞队列 | ArrayBlockingQueue、LinkedBlockingQueue、LoanEventPipeline、优雅停止 |
| 5.3 | 5.3 同步器 | CountDownLatch、Semaphore、CyclicBarrier 的真实场景与替代 |
| 6.1 | 6.1 虚拟线程原理 | 载体线程、挂起、JEP 491 与 pinning 的现状、吞吐对比 |
| 6.2 | 6.2 结构化并发 | StructuredTaskScope 预览 API、Joiner、作用域取消、DashboardService |
| 6.3 | 6.3 虚拟线程落地 | 连接池上限、ThreadLocal → ScopedValue、限流与背压 |
第三部分:语言与平台(第 7–8 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 7.1 | 7.1 record 模式与解构 | record 模式、嵌套解构、LoanState 的扁平表达 |
| 7.2 | 7.2 sealed 层次与穷尽 switch | sealed / permits、穷尽性检查、LoanResult 替代错误码 |
| 7.3 | 7.3 模式匹配的边界 | 守卫 when、null、顺序与可读性、primitive patterns 预览状态 |
| 8.1 | 8.1 JPMS 模块化 | module-info、requires / exports、jdeps、模块化 jar 与 jlink |
| 8.2 | 8.2 FFM API | Linker、MemorySegment、Arena、调用 libisbn 与 native access 告警 |
| 8.3 | 8.3 原生互操作边界 | 崩溃隔离、跨平台分发、JNI 迁移成本、何时用纯 Java |
第四部分:性能(第 9 章)
| 节 | 文章 | 核心内容 |
|---|---|---|
| 9.1 | 9.1 基准测试 | JMH 1.37、Warmup/Measurement/Fork、死代码消除、真实结果表 |
| 9.2 | 9.2 性能剖析 | JFR 录制、jfr summary、ExecutionSample、火焰图与热点定位 |
| 9.3 | 9.3 优化决策 | 分配、锁、批处理的收益核算、回归基线与决策表 |
项目状态推进表
| 章 | libraryd 状态 |
|---|---|
| 1 | Repository<T, ID> 泛型化、Page<T>、型变与类型令牌 |
| 2 | 反射工具、@Audit / @Retry、动态代理事务 |
| 3 | 插件类加载器、javap / ASM / Byte Buddy、libraryd-agent |
| 4 | LoanCounters、volatile 实验、原子类与锁 |
| 5 | 并发容器、LoanEventPipeline、同步器 |
| 6 | 虚拟线程落地、DashboardService 结构化并发、ScopedValue |
| 7 | LoanState / LoanResult、record 模式与穷尽 switch |
| 8 | module-info、jlink、FFM 调用 libisbn |
| 9 | libraryd-benchmarks、JMH、JFR 与优化决策 |
版本与验证
- 主线 JDK 25.0.5(Temurin),Maven 3.9.12。
- 第 3 章:Byte Buddy 1.18.16、ASM 9.11.1。
- 第 9 章:JMH 1.37。
- 预览 API:
StructuredTaskScope(JDK 25 第五次预览)需要--enable-preview;primitive patterns 仍是预览,本书不依赖。 - 验证分三层:
javac --release 25编译、java运行、mvn -q -DskipTests package项目集成。 - 所有性能数字都附机器口径与复现命令;并发实验如实标注「本次复现 / 未复现」。
怎么算读完
读完第 1 章,你应该能解释 Repository<T, ID> 相比 BookRepository 的收益和代价。读完第 3 章,你应该能说清一个类从磁盘到方法区经历了什么。读完第 6 章,你应该能判断一个服务该不该换虚拟线程。读完第 9 章,你应该能在不改代码的情况下先量出一个基线。
如果只能记住一句话:高级不是会用更多 API,而是知道每条规则在什么版本、什么条件下成立,以及它的代价是什么。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。