ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Thinking in Java 4源码导入IDEA运行:详细步骤与常见问题

Thinking in Java 4源码导入IDEA运行:详细步骤与常见问题 简介这是《Thinking in Java》第四版TIJ4的完整配套源码面向初学Java或希望进阶的开发者书中的经典示例经整理后可直接导入IntelliJ IDEA运行免去手动搭建项目的繁琐。压缩包共2059个文件以817个Java源文件为主同时包含class编译文件、xml配置、cpp/py辅助脚本及少量jar依赖整体仅7.07MB轻量且结构清晰。源码覆盖面向对象编程、集合框架、泛型与迭代器、异常处理、多线程同步、网络编程、IO流、反射注解与动态代理等核心主题沿章节目录打开对应示例可边读边运行直观体会类与对象的封装继承多态、ArrayList/HashMap等容器的使用、synchronized与wait/notify的并发控制、Socket/ServerSocket的通信流程等实际写法。源码内还直接保留了IDEA项目配置解压后开箱即用已有953人学习这份源码包适合系统研读TIJ4或快速获取典型Java示例的开发者既能对照书本逐章实践也可作为日常开发中的参考代码库。1. 为什么我建议你把 Thinking in Java 4 源码下载下来而不是只看书很多人在学 Java 的时候都听过《Thinking in Java》这本书第四版对应的是 Java 5/6 的时代书里的代码示例非常经典尤其是并发、内部类、泛型、I/O 这几块即使是放到现在理解起来依然有很强的参考价值。不过大多数人只是把书从头翻到尾真正把配套源码一行行跑过的人反而很少。原因很简单这份源码是 2006 年前后发布的当时的构建工具是 Ant目录结构和现在的 Maven/Gradle 工程差别很大直接拿 IDEA 打开会报一堆错头大的很。我自己当初就是因为这个问题折腾了好几天。把官方下载的 code 压缩包解压后用 IDEA 打开看到的是一堆缺失依赖、编码乱码、找不到 main 方法之类的错误心里一万个问号。后来花时间研究清楚这套源码的组织方式才真正把这本书里的代码跑了起来。这次我把整套流程整理出来标题就一句话Thinking in Java 4 源码导入 IDEA 可直接运行。做成这件事之后你再配合书里的章节去调试代码学习效率完全不一样尤其是那些关于并发、泛型边界的例子亲手改一改、跑一跑比看十遍书都管用。这套源码适合谁我觉得有这么几类人最值得折腾一下正在自学 Java想找一批高质量示例代码来读、来改的初学者准备面试想系统回顾 Java 基础、集合、I/O、并发知识的人以前学过 Java现在想快速把经典语法和思想捡起来的人。简单说只要你手上有这本书或者听说过这本书我都建议你把这套源码跑起来因为这是“纸上谈兵”到“动手实操”之间最省钱省事的一步。2. 整体组织方式与导入思路拆解2.1 官方源码包的结构长什么样这本书的官方源码在 Bruce Eckel 的个人网站上可以下载压缩包解压后是一个叫code的目录里面按章节划分了很多子目录比如concurrency、generics、io、innerclasses、interfaces等。每个子目录里面通常有src子目录存放该章节的 Java 源码文件build.xmlAnt 构建脚本部分目录还有html文件用来配合 Applet 演示程序运行。这套结构的特点是每一章的内容互相独立包名基本是按照书里的章节逻辑来的。但是有个关键点它不满足现代 IDE 对“一个项目一个源码根、一个编译输出路径”的习惯。如果你直接把整个code作为一个项目根目录导入IDEA 根本不知道哪些目录是 source root结果就是满屏红色报错但你看代码本身又没什么问题。弄清楚这一点之后整个导入思路就转变了。我们不追求“官方原样照搬”而是把源码文件重新组织成一个 IDEA 能识别的普通 Java 项目让它能编译、能运行即可。2.2 为什么我不推荐用 Ant 方式去编译官方包里带了 build.xml理论上你可以装上 Ant 之后在命令行执行编译但实际操作下来会碰到几个问题你需要额外安装和配置 Ant 环境学习成本对 Java 初学者并不友好Ant 脚本在现在的 JDK 版本下可能会报一些废弃 API 或 doclet 相关的错误编译产物散落在各个子目录的build里你想在 IDE 里打断点调试体验很差不同章节之间有一些共享代码主要是net.mindview.util包里的工具类Ant 的编译顺序封装在脚本里出了错不好排查。我走的路线是在 IDEA 里新建一个纯 Java 项目把整个code目录里的src内容合理分配成多个源码根统一编译和运行。这套做法不改变原始代码内容只改变 IDE 对代码的“组织视图”。2.3 建立工程时选 JDK 版本有什么讲究Thinking in Java 4 的代码是 Java 5/6 时代写的里面用到了泛型、枚举、自动装箱、可变参数等特性但没有用到 lambda 和 stream。我用 Java 8 编译和运行是完全没问题的后来在 Java 11 上也试过大部分类能过但有少数和 Applet、Swing 相关的类会受模块化影响稍微有些麻烦。所以我的建议是如果你是初学者直接装 Java 8JDK 1.8的 64 位版本和 IDEA 的兼容性最好编译源码基本不出幺蛾子。如果你机器上只有新版本 JDK也不是不能用遇到个别报错我再告诉你处理办法。这里提前给个稳妥的配置方案提示在 IDEA 的 Project Structure 里把 Project SDK 设为 1.8Language Level 设为 8这是我最常用的配置运行书里绝大多数代码都没问题。3. 导入 IDEA 的具体操作步骤3.1 第一步下载、解压与文件检查先去官网下载 code.zip文件不大解压后你会看到一个code文件夹。建议把文件夹放到一个没有中文和空格的路径下比如D:\study\java\thinking-in-java-code这样后面配置各种路径时能省不少事。解压之后打开code目录看一眼确认里面有concurrency、generics这些章节子目录。为了方便识别可以直接把code文件夹改名为TIJ4之类的名字这个不影响内容。接着检查一下总体的源码文件确认是否完整。你可以在 IDEA 的 Terminal 或者 Windows 命令行里进入该目录执行一条命令find . -name *.java | wc -l如果输出数量是 1000 多个说明文件基本完整。这个数字不是绝对值因为不同压缩包版本略有差异但一般不会低于 800。3.2 第二步在 IDEA 里创建普通 Java 项目打开 IDEA选择New Project在左侧选择JavaProject SDK 选 1.8点击 Next给项目取名为TIJ4-Examples然后选择合适的项目路径。不需要勾选任何模板也不需要 Maven/Gradle我们就建一个最原始的 Java 项目。建好之后把这四个东西依次配置好Project SDKFile - Project Structure - Project确认 SDK 是 1.8Language Level 是 8Modules选中当前模块在 Sources 标签页里添加源码根目录Libraries如果有额外依赖就加进去我们这里一般不需要Output 目录默认模块下的out目录即可不用改。这样搭建的好处是够干净后面出问题可以定位到源码本身而不是构建工具。3.3 第三步把书里的源码复制到项目目录这是整个导入流程里最核心的一步。我测试过几种方案包括直接把整个code目录设置为 source root、把code目录软链到项目里等等但最终最稳定、最符合习惯的做法是把code里的所有章节目录直接复制到TIJ4-Examples/src下。具体操作TIJ4-Examples/ └── src/ ├── access/ ├── annotations/ ├── arrays/ ├── concurrency/ ├── containing/ ├── control/ ├── ... └── net/ // 这个目录里是 mindview 工具类你可能会问code目录里每个章节下还有src子目录是不是要单独把每一层src的内容都拷出来对我实操之后发现直接把每个章节目录下的src内容合并到同一个src目录里是最省心的。比如code/concurrency/src下有一堆.java文件你就把concurrency这个文件夹整体复制到项目src下。这样src/concurrency、src/generics这些就成了各个章节的包路径。同时要注意官方源码里有些目录本身就是net/mindview/util这个也是直接复制到src下它在多章代码里被作为工具类引用。net目录在复制时不要漏掉否则后面编译会有一批类报找不到TextFile、OSExecute之类的方法。3.4 第四步标记源码根并修正文件编码复制完之后回到 IDEA项目结构里找到src目录右键标记为Sources Root也就是源码根目录。这一步做完IDEA 就能识别包名和类之间的依赖关系了。但只做这一步还不够因为官方源码是很多年前发布的文件编码很可能是GBK。IDEA 默认读取 UTF-8如果你直接打开会看到一堆乱码中文注释全变“锟斤拷”。处理方法有两个在 IDEA 的 Settings - Editor - File Encodings 里把 Global Encoding 和 Project Encoding 都设为 UTF-8然后在打开文件时手动指定 GBK 转一次另存为 UTF-8如果你只是想让代码能运行、不关心注释文字那可以先不管乱码直接编译运行注释乱码只是显示问题不影响类名和方法名。我建议既然要长期用还是花几分钟统一转码。我用的是 IDEA 自带功能把整个src目录拷进去后右下角可以切换文件编码对所有乱码文件统一转换为 UTF-8。转完之后保存重启 IDEA乱码就基本清干净了。3.5 第五步编译验证在 IDEA 的 Project 窗口里右键项目根目录选择Rebuild ProjectIDEA 会开始编译所有源码。如果这一步没有出现大面积报错说明源码根配置和依赖关系已经搞定了。我第一次编译时大概有十几个文件报错主要集中在两类找不到net.mindview.util.*的包某些文件之间出现了重复类定义。第一类就是net目录没复制全或者没有标记为源码根导致的。第二类往往是因为某些章节目录下存在一个build.xml旁边单独放置的.java文件和src里的某个文件重名了。解决办法是把重复文件从目录中移出去或者直接删除副本保留src下的那一份即可。3.6 第六步直接运行关键示例编译通过之后就可以运行了。比如打开c03或control目录下的ListCharacters.java在文件里找到main方法右键选择Run ListCharacters.main()IDEA 会直接把运行窗口弹出来输出结果。运行前可以在 IDEA 的 Run Configuration 里观察一下它会自动帮你设置好 classpath不需要手动配置。这里要提醒一下有些类的文件名虽然和类名一致但存在跨目录的静态导入比如某些示例用了import static net.mindview.util.Print.*这要求工具类必须先编译但你只要做过一次 Rebuild ProjectIDEA 的增量编译会帮你处理顺序所以基本不会遇到问题。我自己会建议在最初编译通过后优先运行几个“验证信号”强、输出直观的类concurrency/BasicThreads.javainnerclasses/Parcel1.javagenerics/GenericMethods.javaio/DirList.java这四类分别代表多线程、内部类、泛型、I/O 四个核心主题跑通了说明导入工作基本成功。4. 常见问题与排查记录4.1 编译报错程序包 net.mindview.util 不存在这是出现频率最高的问题原因是net目录没有被 IDEA 识别为源码根或者复制源码时遗漏了这个目录。处理办法很简单去src下确认有没有net/mindview/util/Print.java、TextFile.java等文件如果没有去官方包的code/net目录拷贝过来。然后在 IDEA 的 Project 窗口里选中src右键Mark Directory as - Sources Root重新编译即可。这个错误还有一个变种编译时提示OSExecute找不到这十有八九是同一个原因。4.2 编码错乱中文全部变成乱码这个坑真的是避不开。官方源码在 Windows 下压缩时大多是 GBK 编码你用 IDEA 的 UTF-8 打开就会乱。我没找到什么一劳永逸的命令行方案实践下来最稳的办法就是批量转码。IDEA 里如果只打开单个文件能通过右下角的编码切换按钮转换但文件量多的话效率太低。我推荐的做法先用 File - Open 选择某个乱码文件的目录IDEA 会提示文件的编码与实际不符这时选择 Reload 为 GBK然后再全选目录文件用 File - File Properties - File Encoding 把整个目录的编码统一转换成 UTF-8最后保存。整个过程因为是一次性工作花十分钟搞定之后再也不会有乱码。4.3 部分类没有 main 方法怎么运行书里一些例子尤其是 Applet 相关的类根本没有main方法右键运行时 IDEA 会提示“No main method found in class”。这不是导入问题是这类代码本来就要通过appletviewer或者挂在 HTML 文件里跑。遇到这种类我建议直接跳过或者去对应的 HTML 文件里查看运行方式。如果你实在想跑也可以用 IDEA 的 Applet 运行配置但个人觉得没必要在这上面耗费太多精力书里大量有 main 方法的示例已经足够练习了。4.4 编译时内存不足OutOfMemoryError有时候源码数量多IDEA 编译过程中会出现java: outofmemoryerror: insufficient memory。这多半是 IDEA 分配给编译进程的内存太少了。解决办法是修改 IDEA 安装目录下bin/idea64.exe.vmoptions文件把-Xmx调大比如改成2048m或4096m然后重启 IDEA。如果你不想改安装目录的配置文件也可以在 Settings - Build, Execution, Deployment - Compiler 里把Build process heap size调大设置成 1024 或者 2048效果是一样的。4.5 遇到 Lombok 相关报错这个问题比较特殊。后续版本的源码包里有些测试文件或新章节示例可能会引入 Lombok但官方 TIJ4 源码本身没有依赖 Lombok。如果你从其他渠道拿到了一个“增强版”源码包里面加了 Lombok 注解而你的 IDEA 和编译器没有启用注解处理器就会报You arent using a compiler supported by lombok。这时要么安装 Lombok 插件并开启注解处理要么干脆换回官方纯净版源码。4.6 问题速查表现象原因解决方式找不到 net.mindview.util 包net 目录缺失或未标记源码根复制 net 目录并重新标记 Sources Root中文乱码文件实际是 GBKIDEA 用 UTF-8 打开批量转码为 UTF-8或显示层面切换编码没有 main 方法示例本身是 Applet 或组件类跳过或配置 Applet 运行方式编译内存不足IDEA 分配的内存不够修改 vmoptions 或增大 Build process heap size与 Lombok 相关的报错增强版源码引入了 Lombok安装插件并开启注解处理或换官方纯净版5. 我实际跑源码时的一些经验小技巧源码能跑通之后你会发现这是学 Java 不可多得的“玩具场”。我自己在跑的时候总结了几点经验算是给后来的读者一点参考。第一不要只是运行一定要改代码。比如concurrency章节里的EvenGenerator这类例子你可以故意把synchronized去掉用 IDEA 运行几次看看输出乱成什么样再理解为什么加锁。这种交互方式对于理解并发问题特别有效。第二善用 IDEA 的 Evaluate Expression 功能。在某个方法上打断点然后按Alt F8可以直接在当前上下文里执行任意表达式这个方法在调试泛型和集合的时候极其好用比加打印语句快得多。第三把net.mindview.util当成自己的工具库来用。里头的Print、Range、TextFile、OSExecute这些工具类设计得非常干净代码量不大而且很容易读懂。我自己后来写自己的项目时甚至直接把其中几个类拷出来改一改继续用它们很多都是书里设计思想的浓缩体现。第四按章节顺序跑不如按“兴趣导向”跑。我的建议是如果你正在准备面试优先跑generics、concurrency、containing这几章如果你想补基础优先跑innerclasses、polymorphism、interfaces。书本身的顺序更偏学术但你一旦拿到一套可以直接运行的源码怎么用就完全取决于你的目标了。6. 这种导入方式后续还能怎么扩展同一套源码导入 IDEA 的方法不仅适用于《Thinking in Java》这一本书。很多老牌 Java 书籍的配套源码都是类似的风格比如《Java 编程思想》早期版本、某些国外教材的示例代码它们都是“一堆子目录 java 文件 没有构建系统”的状态。你只需要按照这篇文章里的思路复制到一个统一的src下、标记源码根、处理好编码就能让它们在 IDEA 里跑起来。更进一步你可以在跑通源码之后尝试给某些项目加入简单的 JUnit 测试或者把某几个类重构成 Maven 项目。这样一来你不仅学会了知识也顺带熟悉了现代 Java 开发的基本流程。我个人的习惯是每学完一章就复制其中几个我觉得最有价值的类到一个单独的my-experiments包里然后随意修改、注释、测试。到了后期这个包就成了我个人的“Java 实验手册”面试前翻一翻很多知识点都能快速回忆起来。如果你在导入过程中遇到了文章里没提到的问题可以先看看是不是 IDEA 版本差异导致的界面选项位置不同或者试试把所有源码根重新标记一遍再 Rebuild。老源码导入新 IDE 的坑基本就那几个思路对了结果就不会差。本文还有配套的精品资源点击获取
返回列表