具体描述
本书是布鲁斯 • 埃克尔时隔 15 年,继 Thinking in Java 之后又一力作,基于 Java 的 3 个长期支持版(Java 8、11、17),讲解 Java 核心语法,并对 Java 的核心变化进行详述。全书内容通俗易懂,配合示例讲解逐步深入,并结合实际开发需要,从语言底层设计出发,有效帮读者规避一些常见的开发陷阱。
主体部分共 22 章,内容包含对象、操作符、控制流、初始化和清理、复用、多态、接口、内部类、集合、函数式编程、流、异常、代码校验、文件、字符串、泛型等。
本书适合各个层次的 Java 开发者阅读,同时也可作为面向对象程序设计语言以及 Java 语言的参考教材。
作者简介
Bruce Eckel ,C++标准委员会的创始成员之一,知名技术顾问 ,专注于编程语言和软件系统设计方面的研究,常活跃于世界各大顶级技术研讨会。他自1986年以来,累计出版Thinking in C++、Thinking in Java、On Java 8等十余部经典计算机著作,曾多次荣获Jolt 最佳图书奖(“被誉为软件业界的奥斯卡”),其代表作 Thinking in Java被译为中、日、俄、意、波兰、韩等十几种语言,在世界范围内产生广泛影响。
目录信息
1.1 抽象的历程
1.2 对象具有接口
1.3 对象可以提供服务
1.4 隐藏的实现
1.5 复用实现
1.6 继承
1.7 多态
1.8 单根层次结构
1.9 集合
1.10 对象的创建和生命周期
1.11 异常处理
1.12 总结
第2章 安装Java和本书示例
2.1 编辑器
2.2 shell
2.2.1 运行shell
2.2.2 目录(文件夹)
2.2.3 shell 基础操作
2.3 安装Java
2.4 确认安装成功
2.5 安装和运行本书示例
第3章 对象无处不在
3.1 通过引用操作对象
3.2 必须创建所有对象
3.2.1 数据保存在哪里
3.2.2 特殊情况:基本类型
3.2.3 Java 中的数组
3.3 注释
3.4 无须销毁对象
3.4.1 作用域
3.4.2 对象的作用域
3.5 使用class 关键字创建新类型
3.6 方法、参数以及返回值
3.7 编写Java 程序
3.7.1 名称可见性
3.7.2 使用其他组件
3.7.3 static 关键字
3.8 你的第一个Java 程序
3.9 编程风格
3.10 总结
第4章 操作符
4.1 使用Java 操作符
4.2 优先级
4.3 赋值
4.4 算术操作符
4.5 自动递增和自动递减
4.6 关系操作符
4.7 逻辑操作符
4.8 字面量
4.8.1 字面量里的下划线
4.8.2 科学记数法(又称“指数记数法”)
4.9 按位操作符
4.10 移位操作符
4.11 三元操作符
4.12 字符串操作符+ 和+=
4.13 使用操作符时常犯的错误
4.14 类型转换操作符
4.14.1 截尾和舍入
4.14.2 提升
4.15 Java 没有sizeof()
4.16 操作符小结
4.17 总结
第5章 控制流
5.1 true 和false
5.2 if-else
5.3 迭代语句
5.3.1 do-while
5.3.2 for
5.3.3 逗号操作符
5.4 for-in 语法
5.5 return
5.6 break 和continue
5.7 臭名昭著的goto
5.8 switch
5.9 字符串作为选择器
5.10 总结
第6章 初始化和清理
6.1 用构造器保证初始化
6.2 方法重载
6.2.1 区分重载的方法
6.2.2 使用基本类型的重载
6.2.3 通过返回值区分重载方法
6.3 无参构造器
6.4 this 关键字
6.4.1 在构造器中调用构造器
6.4.2 static 的含义
6.5 清理:终结和垃圾收集
6.5.1 finalize() 的作用
6.5.2 你必须执行清理
6.5.3 终止条件
6.5.4 垃圾收集器的工作原理
6.6 成员初始化
6.7 构造器初始化
6.7.1 初始化顺序
6.7.2 静态数据的初始化
6.7.3 显式的静态初始化
6.7.4 非静态实例初始化
6.8 数组初始化
6.8.1 动态数组创建
6.8.2 可变参数列表
6.9 枚举类型
6.10 新特性:局部变量类型推断
6.11 总结
第7章 实现隐藏
7.1 package:库单元
7.1.1 代码组织
7.1.2 创建独一无二的包名
7.1.3 定制工具库
7.1.4 用import 来改变行为
7.1.5 关于包的忠告
7.2 Java 访问权限修饰符
7.2.1 包访问
7.2.2 public:接口访问权限
7.2.3 private:你无法访问它
7.2.4 protected:继承访问权限
7.2.5 包访问权限与公共构造器
7.3 接口和实现
7.4 类的访问权限
7.5 新特性:模块
7.6 总结
第8章 复用
8.1 组合语法
8.2 继承语法
8.3 委托
8.4 组合与继承相结合
8.4.1 确保正确的清理
8.4.2 名称隐藏
8.5 选择组合还是继承
8.6 protected 关键字
8.7 向上转型
8.8 final 关键字
8.8.1 final 数据
8.8.2 final 方法
8.8.3 final 类
8.8.4 关于final 的忠告
8.9 初始化及类的加载
8.10 总结
第9章 多态
9.1 再论向上转型
9.2 难点
9.2.1 方法调用绑定
9.2.2 产生正确的行为
9.2.3 可扩展性
9.2.4 陷阱:“重写”private方法
9.2.5 陷阱:字段与静态方法
9.3 构造器和多态
9.3.1 构造器的调用顺序
9.3.2 继承与清理
9.3.3 构造器内部的多态方法行为
9.4 协变返回类型
9.5 用继承进行设计
第10章 接口
10.1 抽象类和抽象方法
10.2 接口定义
10.2.1 默认方法
10.2.2 多重继承
10.2.3 接口中的静态方法
10.2.4 作为接口的Instrument
10.3 抽象类与接口
10.4 完全解耦
10.5 组合多个接口
10.6 通过继承来扩展接口
10.7 适配接口
10.8 接口中的字段
10.9 嵌套接口
10.10 接口和工厂
10.11 新特性:接口的private方法
10.12 新特性:密封类和密封接口
10.13 总结
第11章 内部类
11.1 创建内部类
11.2 到外部类的链接
11.3 使用.this 和.new
11.4 内部类和向上转型
11.5 在方法和作用域中的内部类
11.6 匿名内部类
11.7 嵌套类
11.7.1 接口中的类
11.7.2 从多层嵌套的内部类中 访问外部成员
11.8 为什么需要内部类
11.8.1 闭包与回调
11.8.2 内部类与控制框架
11.9 继承内部类
11.10 内部类可以被重写吗
11.11 局部内部类
11.12 内部类标识符
11.13 总结
第12章 集合
12.1 泛型和类型安全的集合
12.2 基本概念
12.3 添加一组元素
12.4 打印集合
12.5 List
12.6 Iterator
12.7 LinkedList
12.8 Stack
12.9 Set
12.10 Map
12.11 新特性:记录(record)类型
12.12 Queue
12.13 Collection 和Iterator 的对比
12.14 for-in 和迭代器
12.15 总结
第13章 函数式编程
13.1 旧方式与新方式
13.2 lambda 表达式
13.3 方法引用
13.3.1 Runnable
13.3.2 未绑定方法引用
13.3.3 构造器方法引用
13.4 函数式接口
13.4.1 带有更多参数的函数式接口
13.4.2 解决缺乏基本类型函数式接口的问题
13.5 高阶函数
13.6 闭包
13.7 函数组合
13.8 柯里化和部分求值
13.9 纯函数式编程
13.10 总结
第14章 流
14.1 Java 8 对流的支持
14.2 流的创建
14.2.1 随机数流
14.2.2 int 类型的区间范围
14.2.3 generate()
14.2.4 iterate()
14.2.5 流生成器
14.2.6 Arrays
14.2.7 正则表达式
14.3 中间操作
14.3.1 跟踪与调试
14.3.2 对流元素进行排序
14.3.3 移除元素
14.3.4 将函数应用于每个流元素
14.3.5 在应用map() 期间组合流
14.4 Optional 类型
14.4.1 便捷函数
14.4.2 创建Optional
14.4.3 Optional 对象上的操作
14.4.4 由Optional 组成的流
14.5 终结操作
14.5.1 将流转换为一个数组
14.5.2 在每个流元素上应用某个 终结操作
14.5.3 收集操作
14.5.4 组合所有的流元素
14.5.5 匹配
14.5.6 选择一个元素
14.5.7 获得流相关的信息
14.6 小结
第15章 异常
15.1 概念
15.2 基本的异常
15.3 捕捉异常
15.3.1 try 块
15.3.2 异常处理程序
15.4 创建自己的异常
15.5 异常说明
15.6 捕捉任何异常
15.6.1 多重捕捉
15.6.2 栈轨迹
15.6.3 重新抛出异常
15.6.4 异常链
15.7 标准Java 异常
15.8 新特性:更好的NullPointerException报告机制
15.9 使用finally 执行清理
15.9.1 finally 是干什么用的
15.9.2 在return 期间使用finally
15.9.3 缺陷:异常丢失
15.10 异常的约束
15.11 构造器
15.12 try-with-resources 语句
15.12.1 细节揭秘
15.12.2 新特性:try-withresources中的实际上的最终变量
15.13 异常匹配
15.14 其他可选方式
15.14.1 历史
15.14.2 观点
15.14.3 把异常传递到控制台
15.14.4 将“检查型异常”转换为“非检查型异常”
15.15 异常使用指南
15.16 小结
附记 异常的奇异世界
第16章 代码校验
16.1 测试
16.1.1 单元测试
16.1.2 测试覆盖率的幻觉
16.2 前置条件
16.2.1 断言
16.2.2 DbC + 单元测试
16.2.3 使用Guava 里的前置 条件
16.3 测试驱动开发
16.4 日志
16.5 调试
16.5.1 使用JDB 进行调试
16.5.2 图形调试器
16.6 基准测试
16.6.1 微基准测试
16.6.2 介绍JMH
16.7 分析与优化
16.8 样式检查
16.9 静态错误分析
16.10 代码审查
16.11 结对编程
16.12 重构
16.13 持续集成
16.14 总结
第17章 文件
17.1 文件和目录路径
17.1.1 选择Path 的片段
17.1.2 分析Path
17.1.3 添加或删除路径片段
17.2 目录
17.3 文件系统
17.4 监听Path
17.5 查找文件
17.6 读写文件
17.7 小结
第18章 字符串
18.1 不可变的字符串
18.2 重载+ 与StringBuilder
18.3 无意识的递归
18.4 对字符串的操作
18.5 格式化输出
18.5.1 printf()
18.5.2 System.out.format()
18.5.3 Formatter 类
18.5.4 格式说明符
18.5.5 Formatter 转换
18.5.6 String.format()
18.6 新特性:文本块
18.7 正则表达式
18.7.1 基础
18.7.2 创建正则表达式
18.7.3 量词
18.7.4 Pattern 和Matcher
18.7.5 split()
18.7.6 替换操作
18.7.7 reset()
18.7.8 正则表达式和JavaI/O
18.8 扫描输入
18.8.1 Scanner 分隔符
18.8.2 使用正则表达式扫描
18.9 StringTokenizer
18.10 总结
第19章 反射
19.1 为什么需要反射
19.2 Class 对象
19.2.1 类字面量
19.2.2 泛型类的引用
19.2.3 cast() 方法
19.3 转型前检查
19.3.1 使用类字面量
19.3.2 动态的instanceof
19.4 注册工厂
19.5 Instanceof 与Class 的等价性
19.6 运行时的类信息
19.7 动态代理
19.8 使用Optional
19.8.1 标签接口
19.8.2 模拟对象和桩
19.9 接口和类型信息
19.10 总结
第20章 泛型
20.1 和C++ 的对比
20.2 简单泛型
20.2.1 元组库
20.2.2 栈类
20.2.3 RandomList
20.3 泛型接口
20.4 泛型方法
20.4.1 可变参数和泛型方法
20.4.2 通用Supplier
20.4.3 简化元组的使用
20.4.4 Set 实用工具
20.5 构建复杂模型
20.6 类型擦除的奥秘
20.6.1 C++ 的实现方法
20.6.2 迁移的兼容性
20.6.3 类型擦除存在的问题
20.6.4 边界的行为
20.7 对类型擦除的补偿
20.7.1 创建类型实例
20.7.2 泛型数组
20.8 边界
20.9 通配符
20.9.1 编译器有多聪明?
20.9.2 逆变性
20.9.3 无界通配符
20.9.4 捕获转换
20.10 问题
20.10.1 基本类型不可作为 类型参数
20.10.2 实现参数化接口
20.10.3 类型转换和警告
20.10.4 重载
20.10.5 基类会劫持接口
20.11 自限定类型
20.11.1 奇异递归泛型
20.11.2 自限定
20.11.3 参数协变性
20.12 动态类型安全
20.13 异常
20.14 混型
20.14.1 C++ 中的混型
20.14.2 与接口混合
20.14.3 使用装饰器模式
20.14.4 与动态代理混合
20.15 潜在类型机制 20.15.1 Python 中的潜在类型 机制
20.15.2 C++ 中的潜在类型 机制
20.15.3 Go 中的潜在类型 机制
20.15.4 Java 中的直接潜在 类型机制
20.16 对于缺少(直接的)潜在类型 机制的补偿
20.16.1 反射
20.16.2 将方法应用于序列
20.17 Java 8 中的辅助潜在类型 机制
20.18 总结:转型真的这么糟糕吗?
第21章 数组
21.1 数组为何特殊
21.2 数组是一等对象
21.3 返回数组
21.4 多维数组
21.5 数组和泛型
21.6 Arrays.fill()
21.7 Arrays.setAll()
21.8 增量生成器
21.9 随机数生成器
21.10 泛型和基本类型数组
21.11 修改已有的数组元素
21.12 关于数组并行
21.12.1 策略
21.12.2 parallelSetAll()
21.13 数组实用工具
21.14 数组复制
21.15 数组比较
21.16 流和数组
21.17 数组排序
21.17.1 使用Arrays.sort()
21.17.2 并行排序
21.18 用Arrays.binarySearch() 进行 二分查找
21.19 用parallelPrefix() 进行累积 计算
21.20 总结 / 806
附录A 补充内容
附录B 积极看待C++与Java的遗产
· · · · · · (收起)
读后感
作为本书译者之一,坦白地说翻译此书最主要的原因是作者Bruce Eckel是我上学时的偶像(确实是看他的书长大的),而Java则是我做手机游戏研发接触的第一门语言。 作为一名文科生出身的我,甚至可以说如果没有Bruce,自己有可能不会那么坚持的选择编程作为职业。而如果没有Java,...
作为本书译者之一,坦白地说翻译此书最主要的原因是作者Bruce Eckel是我上学时的偶像(确实是看他的书长大的),而Java则是我做手机游戏研发接触的第一门语言。 作为一名文科生出身的我,甚至可以说如果没有Bruce,自己有可能不会那么坚持的选择编程作为职业。而如果没有Java,...
作为本书译者之一,坦白地说翻译此书最主要的原因是作者Bruce Eckel是我上学时的偶像(确实是看他的书长大的),而Java则是我做手机游戏研发接触的第一门语言。 作为一名文科生出身的我,甚至可以说如果没有Bruce,自己有可能不会那么坚持的选择编程作为职业。而如果没有Java,...
作为本书译者之一,坦白地说翻译此书最主要的原因是作者Bruce Eckel是我上学时的偶像(确实是看他的书长大的),而Java则是我做手机游戏研发接触的第一门语言。 作为一名文科生出身的我,甚至可以说如果没有Bruce,自己有可能不会那么坚持的选择编程作为职业。而如果没有Java,...
作为本书译者之一,坦白地说翻译此书最主要的原因是作者Bruce Eckel是我上学时的偶像(确实是看他的书长大的),而Java则是我做手机游戏研发接触的第一门语言。 作为一名文科生出身的我,甚至可以说如果没有Bruce,自己有可能不会那么坚持的选择编程作为职业。而如果没有Java,...
用户评价
这本书简直是C++开发者的噩梦和Java新手的福音,尤其是对于我这种从C++的指针和内存管理地狱里爬出来的人来说。我原本以为Java会简单很多,但当我翻开这本书时,我才发现自己对面向对象编程的理解有多么肤浅。它不是那种给你一堆API文档让你自己啃的参考手册,更像是一个经验丰富的老兵在手把手教你如何像一个真正的Java程序员那样思考。从一开始的类和对象的基本概念,到后来深入到接口、继承、多态的精妙运用,作者的讲解方式极其清晰,总能用生活化的例子把复杂的理论讲得透彻。比如,书中对“组合优于继承”的论述,让我彻底改变了过去那种堆砌继承层次的糟糕设计习惯。而且,它不仅仅停留在语法层面,更强调了“为什么”要这样设计,这种设计哲学层面的引导,对于构建健壮、可维护的系统至关重要。读完前面几章,我感觉自己对JVM的工作原理都有了更直观的认识,这对于后续调试和性能优化打下了坚实的基础。
我是一个对代码质量有极高要求的工程师,所以通常在选购技术书籍时都会非常谨慎,生怕买到一本只停留在表面、代码风格老旧的“古董”。幸运的是,这本《On Java》完全没有这个问题。它的示例代码非常现代化,紧跟Java语言发展的步伐,而且最重要的,它对设计模式的讲解是嵌入在具体问题解决方案中的,而不是孤立地罗列。比如,当讨论到灵活的算法切换时,它自然而然地引入了策略模式(Strategy Pattern)的实现,并且展示了如何用接口和抽象类来优雅地实现它。这种将理论与实践无缝结合的方式,极大地提高了我的学习效率。我甚至开始在自己的日常工作中,有意识地去寻找那些可以通过设计模式优化现有结构的地方。这本书的排版和图示也做得相当不错,复杂的数据结构和流程图清晰明了,让复杂的概念不再令人望而生畏。
坦白说,这本书的阅读体验是充满挑战的,它绝对不是那种可以轻松读完然后放在书架上充门面的书。尤其是涉及到JVM内存模型和垃圾回收机制的那部分内容,我不得不反复阅读,甚至需要借助一些外部的资源来辅助理解。作者似乎有意将难度设定在略高于初学者的水平,旨在筛选出那些真正愿意沉下心来掌握这门语言精髓的读者。在我看来,这反而是一种优点。它迫使我走出舒适区,去深挖那些平时开发中轻易被框架和库所掩盖的底层细节。比如,书中关于类加载器(ClassLoader)层级结构的探讨,让我对模块化编程有了全新的认识。这种不回避复杂性的态度,正是专业技术书籍所应有的担当。读完这些章节,我不再满足于仅仅知道`System.gc()`可以被调用,而是明白了为什么它常常“不起作用”。
我最欣赏这本书的地方在于其严谨的逻辑连贯性和对“实践正确性”的执着。它不仅仅是告诉你“这样做”,更关键的是解释了“为什么要这样做,以及不这样做会有什么后果”。这种对编程规范和最佳实践的深入探讨,贯穿了全书。例如,在文件I/O和网络编程的章节中,作者对资源关闭的处理堪称典范,他详细对比了传统`try-finally`和Java 7引入的Try-with-Resources语句的优劣,清晰地展示了后者是如何从根本上杜绝资源泄漏这一常见错误的。这种对健壮性代码的极致追求,让这本书超越了一本单纯的技术教材,更像是一部软件工程的准则手册。它教会了我如何写出不仅能运行,而且是安全、高效、易于维护的代码。对于任何想把Java作为长期职业方向的人来说,这本书提供的思想深度是无可替代的宝贵财富。
这本书的深度绝对不是那些市面上泛滥的“速成”读物能比拟的。我刚开始只是想快速了解一下Java的新特性,结果一头扎进了它对并发编程和异常处理的详尽剖析中。读到关于线程同步的那几章,我简直是心惊胆战,作者毫不留情地揭示了在多线程环境下,那些看似微不足道的竞态条件是如何轻易地摧毁程序的正确性的。他用大量的代码片段演示了`synchronized`关键字的底层机制,以及`volatile`的真正含义,这比我之前在各种博客上零散看到的描述要系统和深刻得多。更让我印象深刻的是,书中对Java 5引入的泛型(Generics)的讲解,它没有停留在泛型集合类的使用上,而是深入到了类型擦除的底层实现,这对于理解某些框架库的内部工作原理非常有帮助。可以说,这本书让你从“会写Java代码”升级到“理解Java的灵魂”。
干,我大学时候如果有这本书,我想我一毕业就会去写java!
非常好的java书
这本书,怎么说呢!是thiking in java 第四版的升级版,这本书中的代码主要是讲Java 17的一个版本。这本书很渊博值得深度,但是也很难读懂对于一个新手来说
时隔多年Bruce又一力作,可以看成是《Thinking in Java》的升级版。新书延承老版本讲解编程思想的同时,舍弃了过时的内容并加入了Java8之后版本的新特性。CompeleteFuture、Stream和函数式编程这三部分讲的还不错,值得一读。
这是一本很特别的编程语言“入门”书籍,虽然是介绍Java,但书中不乏对Java的各种吐槽。作者写作的角度很高,介绍语言细节但又不拘泥于细节,着重于传达编程思想。