# learning-java-basics **Repository Path**: libingquan/learning-java-basics ## Basic Information - **Project Name**: learning-java-basics - **Description**: java 开发学习记录 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-05 - **Last Updated**: 2026-07-03 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java 基础学习项目 一个面向 C++ 开发者的 Java 学习项目,通过对比学习的方式快速掌握 Java 核心知识。 ## 项目概述 - **Java 版本**: JDK 17+ - **构建工具**: Maven - **测试框架**: JUnit 5 - **目标读者**: 有 C++ 基础,正向 Java 转型的开发者 ## 运行指南 ### 环境要求 | 工具 | 版本要求 | 说明 | |------|----------|------| | JDK | 17+ | [下载地址](https://adoptium.net/) | | Maven | 3.6+ | [下载地址](https://maven.apache.org/download.cgi) | 安装后验证: ```bash java -version mvn -version ``` ### Maven 常用命令 | 命令 | 作用 | |------|------| | `mvn compile` | 编译源代码(生成 `target/classes`) | | `mvn test` | 编译并运行所有测试 | | `mvn clean` | 清理 `target` 目录 | | `mvn clean test` | 清理后重新编译测试 | | `mvn test -Dtest=XxxTest` | 运行指定测试类 | | `mvn test -Dtest=XxxTest,YyyTest` | 运行多个测试类 | | `mvn test -Dtest="*Test"` | 运行所有测试类 | | `mvn dependency:tree` | 查看依赖树 | ### 运行示例代码 每个示例类都有 `main` 方法,可独立运行: ```bash # 1. 先编译 mvn compile # 2. 运行示例(使用类的完全限定名) java -cp target/classes org.example.basics.s03_types_and_reference.P04StringDemo # 常用示例快速运行 java -cp target/classes org.example.basics.s01_project_structure.P01PackageVsInclude java -cp target/classes org.example.basics.s02_basic_syntax_diff.P01NoPointerDemo java -cp target/classes org.example.basics.s03_types_and_reference.P03ValueVsReference java -cp target/classes org.example.basics.s06_inheritance.P01InheritanceDemo java -cp target/classes org.example.basics.s07_interface.P01InterfaceDemo java -cp target/classes org.example.basics.s08_polymorphism.P01PolymorphismDemo java -cp target/classes org.example.collections.s01_list.P01ArrayListDemo java -cp target/classes org.example.collections.s02_set.P01HashSetDemo java -cp target/classes org.example.collections.s03_map.P02HashMapInternal java -cp target/classes org.example.collections.s04_stream.P01StreamBasic ``` ### 运行单元测试 ```bash # 运行所有测试 mvn test # 运行单个测试类 mvn test -Dtest="StringTest" mvn test -Dtest="ReferenceTest" mvn test -Dtest="CollectionTest" # 运行多个测试类 mvn test -Dtest="StringTest,ReferenceTest" # 查看详细测试输出 mvn test -Dtest="CollectionTest" -Dsurefire.useFile=false ``` ### IDE 运行 #### IntelliJ IDEA(推荐) 1. File → Open → 选择 `pom.xml` 2. 点击 "Open as Project" 3. 打开任意 `.java` 文件,右键 → Run 'P01HashSetDemo' 4. 或右键 `*Test.java` → Run 'XxxTest' 5. 快捷键:`Shift+F10` 运行上次程序 #### VS Code 1. 安装扩展:Java Extension Pack 2. 打开项目文件夹 3. 右键 `.java` 文件 → Run Java 4. 右键 `*Test.java` → Run Test ### 目录说明 | 目录 | 说明 | |------|------| | `src/main/java/` | Java 源代码 | | `src/main/resources/` | 资源文件(笔记、配置) | | `src/test/java/` | 单元测试代码 | | `target/classes/` | 编译后的 `.class` 文件 | | `target/surefire-reports/` | 测试报告 | ### 常见问题 **Q: `mvn` 命令找不到?** ```bash # 确保 Maven 已安装并配置到 PATH export PATH=$PATH:/path/to/maven/bin ``` **Q: 测试运行失败?** ```bash # 清理后重试 mvn clean test ``` **Q: 如何查看测试覆盖率?** ```bash # 添加 JaCoCo 插件到 pom.xml,然后运行 mvn test jacoco:report ``` ## 学习路线图 ``` 阶段1: 消除思维惯性 → 阶段2: OOP核心 → 阶段3: 集合框架 → 阶段4: 函数式编程 (已完成) (已完成) (已完成) (已完成) ↓ 阶段6: 多线程 ← 阶段5: I/O (已完成) (已完成) ``` ## 已完成内容 ### 阶段1:消除思维惯性 ✅ 从 C++ 转向 Java,首先需要消除语言惯性。 | 模块 | 内容 | 示例 | |------|------|------| | s01 | 项目结构 | package vs include、import 原理 | | s02 | 语法差异 | 无指针、无全局函数、无头文件 | | s03 | 类型系统 | 基本类型、引用、值传递、String不可变 | ### 阶段2:OOP 核心 ✅ Java 是纯面向对象语言,OOP 是核心。 | 模块 | 内容 | 示例 | |------|------|------| | s04 | 类与对象 | static vs 实例方法、构造器 | | s05 | 封装 | 访问控制、getter/setter、JavaBean | | s06 | 继承 | 单继承、super、@Override | | s07 | 接口 | 多实现、default方法、函数式接口 | | s08 | 多态 | 向上/向下转型、instanceof、抽象类 | | s09 | 泛型 | 类型擦除、通配符、PECS原则 | | s10 | 异常处理 | checked/unchecked、try-with-resources | | s11 | 枚举 | enum带字段/方法、EnumSet/EnumMap | | s12 | Record | 不可变数据载体(自动生成equals/hashCode) | ### 阶段3:集合框架 ✅ Java 集合是日常开发中使用最频繁的 API。 | 模块 | 内容 | 示例 | |------|------|------| | s01_list | List | ArrayList、LinkedList、迭代器、fail-fast | | s02_set | Set | HashSet、TreeSet、hashCode+equals契约 | | s03_map | Map | HashMap、TreeMap、底层结构(数组+链表/红黑树) | | s04_stream | Stream | filter/map/reduce、惰性求值、分组、并行流 | | s05_queue | Queue/Deque | PriorityQueue、ArrayDeque、栈/队列双模式 | ### 阶段4:函数式编程 ✅ Java 8+ 引入的函数式特性,让代码更简洁。 | 模块 | 内容 | 示例 | |------|------|------| | s01_lambda | Lambda 表达式 | 语法演进、变量捕获(effectively final) | | s02_method_reference | 方法引用 | 四种方法引用(静态/实例/特定类型/构造器) | | s03_functional_interface | 函数式接口 | Predicate/Function/Consumer/Supplier | | s04_optional | Optional | 消灭 NullPointerException 的函数式方案 | | s05_stream_advanced | Stream 进阶 | flatMap、reduce 三种形式、并行流 | ### 阶段5:I/O ✅ | 模块 | 内容 | 示例 | |------|------|------| | s01_byte_stream | 字节流 | InputStream/OutputStream、BufferedStream、DataStream | | s02_char_stream | 字符流 | Reader/Writer、BufferedReader、编码转换 | | s03_decorator | 装饰器模式 | Java I/O 装饰器模式、自定义装饰器 | | s04_nio | NIO | Buffer/Channel、MappedByteBuffer、Path/Files | ### 阶段6:多线程 ✅ | 模块 | 内容 | 示例 | |------|------|------| | s01_thread_basics | 线程基础 | Thread/Runnable、start/join/interrupt/daemon | | s02_synchronization | 同步机制 | synchronized、wait/notify、生产者-消费者 | | s03_juc_atomic | JUC 原子/并发集合 | AtomicInteger、ConcurrentHashMap、BlockingQueue | | s04_lock | 显式锁 | ReentrantLock、ReadWriteLock、Condition | | s05_thread_pool | 线程池 | ExecutorService、Future/Callable、CompletableFuture | ## 项目结构 ``` src/main/java/org/example/ ├── basics/ # Java 基础 │ ├── s01_project_structure/ # 项目工程结构 │ ├── s02_basic_syntax_diff/ # 语法差异 │ ├── s03_types_and_reference/ # 类型与引用 │ ├── s04_class_and_object/ # 类与对象 │ ├── s05_encapsulation/ # 封装 │ ├── s06_inheritance/ # 继承 │ ├── s07_interface/ # 接口 │ ├── s08_polymorphism/ # 多态 │ ├── s09_generic/ # 泛型 │ ├── s10_exception/ # 异常处理 │ └── s11_enum/ # 枚举 ├── collections/ # 集合框架 │ ├── s01_list/ # List 家族 │ ├── s02_set/ # Set 家族 │ ├── s03_map/ # Map 家族 │ ├── s04_stream/ # Stream API │ └── s05_queue/ # Queue & Deque ├── functional/ # 函数式编程 │ ├── s01_lambda/ # Lambda 表达式 │ ├── s02_method_reference/ # 方法引用 │ ├── s03_functional_interface/ # 函数式接口 │ ├── s04_optional/ # Optional │ └── s05_stream_advanced/ # Stream 进阶 ├── io/ # I/O │ ├── s01_byte_stream/ # 字节流 │ ├── s02_char_stream/ # 字符流 │ ├── s03_decorator/ # 装饰器模式 │ └── s04_nio/ # NIO └── threads/ # 多线程 ├── s01_thread_basics/ # 线程基础 ├── s02_synchronization/ # 同步机制 ├── s03_juc_atomic/ # JUC 原子/并发集合 ├── s04_lock/ # 显式锁 └── s05_thread_pool/ # 线程池 src/test/java/org/example/ # 单元测试 ``` ## C++ vs Java 核心差异速查 | 主题 | C++ | Java | |------|-----|------| | 内存管理 | 手动 new/delete | GC 自动回收 | | 头文件 | .h + .cpp 分离 | 所有代码在 .java 中 | | 全局函数 | 可以独立于类 | 所有方法必须在类中 | | 继承 | 多继承 | 单继承 + 多接口 | | 字符串 | std::string (可变) | String (不可变) | | 字符串比较 | == 比较内容 | == 比较引用,equals 比较内容 | | 异常 | 可抛出任意类型 | 只抛 Throwable 子类,checked/unchecked 分明 | | 枚举 | `enum { A, B }` 整数常量 | 完整类对象(字段/方法/接口) | | 参数传递 | 值/指针/引用三种 | 只有值传递(引用类型传引用副本) | | 泛型/模板 | 编译期代码生成(模板) | 编译后类型擦除 | | lambda | `[&]`按引用 `[=]`按值捕获 | 只按值捕获 effectively final 变量 | | 资源管理 | RAII(析构函数自动清理) | try-with-resources(AutoCloseable) | | 数据载体 | struct 聚合初始化 | record (Java 16+) 自动生成 equals/hashCode | | 容器 | std::vector/list/unordered_map | ArrayList/LinkedList/HashMap | | Stream | C++20 ranges / std::views | Stream API + parallelStream() | | Optional | C++17 std::optional | Optional (更丰富的 API: filter/flatMap) | | 线程池 | 需第三方库 | 内置 ExecutorService | ## 推荐 IDE - **IntelliJ IDEA** — 最推荐的 Java IDE,智能提示强大 - **VS Code** — 轻量级,安装 Java Extension Pack - **Eclipse** — 老牌 IDE,插件丰富 ## 学习方法论 > 学习一个新语言/框架,不能只停留在"怎么用",更要追问"为什么这样设计"和"内部怎么实现"。 ### 三层学习框架 每个知识点按三层递进: | 层次 | 核心问题 | 目标 | |------|----------|------| | **设计动机(Why)** | 这个特性要解决什么问题?没有它之前有什么痛点? | 能判断"什么时候该用" | | **工具体系与选型(What & When)** | 有哪些可用工具?各自的适用场景和取舍是什么?怎么选? | 能在多个方案中做出正确选择 | | **核心原理(How)** | 底层数据结构、算法、设计模式是什么?为什么这样实现? | 能理解边界行为,能排查深层 bug | **示例 —— 学习 HashMap:** 1. Why:为什么需要哈希表?O(1) 查找解决了数组/链表的什么问题? 2. What:HashMap vs TreeMap vs LinkedHashMap,各自的适用场景(无序/有序/插入顺序) 3. How:数组+链表/红黑树 → hash 扰动函数 → 扩容机制 → 树化阈值为什么是 8 ### 知识点优先级——把时间花在刀刃上 不是所有知识点都同等重要。按优先级分配学习时间: **P0 — 生存必备(先学)**:不会这些就写不出 Java 程序。 | 模块 | 内容 | |------|------| | 类型系统 | 基本类型、引用类型、值传递、String 不可变 | | OOP 核心 | 类/对象、封装、继承、接口、多态 | | 异常处理 | checked/unchecked、try-with-resources | | 集合基础 | ArrayList、HashSet、HashMap — 日常最常用的三种容器 | | Lambda 基础 | 语法、变量捕获、常用函数式接口 | **P1 — 日常高频(第二批)**:实际项目中每天都在用。 | 模块 | 内容 | |------|------| | 泛型 | 类型擦除、通配符、PECS 原则 | | Stream API | filter/map/collect、惰性求值 | | Optional | 消灭 NPE 的函数式方案 | | 枚举 & Record | enum 带方法/字段、不可变数据载体 | | 常用 API | java.time(时间)、BigDecimal(精确计算) | | 线程基础 | Thread/Runnable、synchronized、ExecutorService | | 并发集合 | ConcurrentHashMap、BlockingQueue | | I/O 基础 | BufferedReader/BufferedWriter、InputStream/OutputStream | **P2 — 深化理解(按需)**:让你从"会用"到"真正理解"。 | 模块 | 内容 | |------|------| | JVM | 运行时数据区、GC 算法、类加载机制 | | 反射 | 运行时类型信息、动态代理 | | JMM | volatile、happens-before、内存可见性 | | NIO | Buffer/Channel、Path/Files | | 显式锁 | ReentrantLock、ReadWriteLock、Condition | | 序列化 | Serializable、transient、现代替代方案 | **P3 — 锦上添花(兴趣驱动)**:特定场景才需要。 | 模块 | 内容 | |------|------| | SPI 机制 | ServiceLoader、可插拔架构 | | 高级 JVM | 字节码、执行引擎、编译优化 | | 动态代理 | JDK Proxy、CGLIB | ### 工具优先级——先学"首选",再学"备选" 每个工具类别里不需要平均用力。先掌握 80% 场景下的默认选择: | 领域 | 首选(覆盖 80%+ 场景) | 后学 | |------|------------------------|------| | List | `ArrayList` | `LinkedList`(仅频繁头/中部插入删除时用) | | Map | `HashMap` | `TreeMap`(需排序)、`LinkedHashMap`(需保序) | | Set | `HashSet` | `TreeSet`(需排序) | | 同步 | `synchronized` | `ReentrantLock`(仅需公平锁/tryLock 时) | | 创建线程 | `ExecutorService` 线程池 | `new Thread()` 裸线程 | | IO 读写 | `BufferedReader`/`BufferedWriter` | `FileReader`/`FileWriter` 裸流 | | 异常设计 | 非受检异常(`RuntimeException`) | 受检异常(仅可恢复+必须处理时) | | Stream | `filter/map/collect` | `flatMap`、`reduce` 多参数变体 | > 原则:学一个新工具类别时,先问"默认用哪个",搞透这一个,再按需扩展。 ### C++ 对比的三层深度 既然有 C++ 基础,对比学习是捷径——但不能只停在语法层面: 1. **语法层(表面)**:`std::vector` → `ArrayList`,直接翻译 2. **设计哲学层(中层)**:为什么 Java 选单继承+接口,而 C++ 选多继承?语言设计者各自优先保证什么?Java 优先简单和安全,C++ 优先灵活和零开销 3. **运行时行为层(深层)**:同一段逻辑,JVM 和 C++ 编译后的内存布局、执行路径有何不同?(如虚函数调用:C++ vtable 指针 vs JVM invokevirtual 字节码) ### 输出倒逼输入 你是否"真的懂了"?试一下: - **逆向设计法**:学完 HashMap 后,关掉源码,自己设计一个哈希表,再对比 JDK 实现——差距就是真正的收获 - **纯文本复述法**:不看代码,用纯文字写出 `HashMap.put()` 从调用到写入桶的完整执行流程(包括 hash 扰动、扩容触发条件、树化阈值、位运算优化)——卡住的地方就是盲区 ### 核心源码阅读优先级 不是所有 JDK 类都需要读源码,优先读这三类: | 优先级 | 类别 | 代表类 | 收获 | |--------|------|--------|------| | ⭐⭐⭐ | 数据结构实现 | `HashMap`, `ArrayList`, `LinkedList` | 理解算法在工程中的真实权衡 | | ⭐⭐⭐ | 并发基石 | `AbstractQueuedSynchronizer`, `ThreadPoolExecutor` | Doug Lea 的设计是并发编程教科书 | | ⭐⭐ | 设计模式典范 | `java.io` 包(装饰器模式) | 看设计模式在真实代码中如何落地 | ### 知识连线——把散点串成网 单个知识点理解了,但**知识点之间的连线**才是融会贯通的关键。学习时主动画"知识链": ``` synchronized → 对象头(Mark Word) → 锁升级(偏向→轻量→重量) → JVM monitor 机制 Stream 惰性求值 → Spliterator → ForkJoinPool → 工作窃取算法 ``` ### 微型项目串联练习 按"知识点"组织的学习完成后,用 1-2 个微型项目把分散的知识串起来: | 项目 | 串联知识点 | |------|-----------| | 简易 DI 容器 | 反射 + 泛型 + 注解 + 单例模式 | | 简易 HTTP 服务器 | IO + 线程池 + 并发集合 + 异常处理 | | Markdown 解析器 | Stream + Optional + Record + 策略模式 | ## 参考资料 - [Java 官方文档](https://docs.oracle.com/javase/) - [Maven 中央仓库](https://mvnrepository.com/) - [JUnit 5 文档](https://junit.org/junit5/docs/current/user-guide/)