本書是布魯斯·?藸枙r隔 15 年,繼 Thinking in Java 之后又一力作,基于 Java 的 3 個長期支持版(Java 8、11、17),講解 Java 核心語法,并對 Java 的核心變化進行詳述。全書內(nèi)容通俗易懂,配合示例講解逐步深入,并結(jié)合實際開發(fā)需要,從語言底層設(shè)計出發(fā),有效幫讀者規(guī)避一些常見的開發(fā)陷阱。
主體部分共 22 章,內(nèi)容包含對象、操作符、控制流、初始化和清理、復(fù)用、多態(tài)、接口、內(nèi)部類、集合、函數(shù)式編程、流、異常、代碼校驗、文件、字符串、泛型等。
本書適合各個層次的 Java 開發(fā)者閱讀,同時也可作為面向?qū)ο蟪绦蛟O(shè)計語言以及 Java 語言的參考教材。
基于Java 8、11、17,Thinking in系列書籍作者Bruce Eckel重講Java的編程!
1.查漏寶典:涵蓋Java關(guān)鍵特性的設(shè)計原理和應(yīng)用方法
2.避坑指南:以產(chǎn)業(yè)實踐的得失為鑒,指明Java開發(fā)者不可不知的設(shè)計陷阱
3.小白大神皆可讀:適合不同層次的Java開發(fā)者反復(fù)翻閱
4.大咖領(lǐng)讀:3位一線技術(shù)專家?guī)悴鸾鈺须y點內(nèi)容,總結(jié)Java開發(fā)精要
【作者簡介】
布魯斯·?藸枺˙ruce Eckel)
C 標準委員會的創(chuàng)始成員之一,技術(shù)顧問,專注于編程語言和軟件系統(tǒng)設(shè)計方面的研究,常活躍于世界各大技術(shù)研討會。他自 1986 年以來,累計出版 Thinking in C 、Thinking in Java、On Java 8 等十余部計算機,曾多次榮獲 Jolt 最佳圖書獎(被譽為軟件業(yè)界的奧斯卡),其代表作 Thinking in Java 被譯為中文、日文、俄文、意大利文、波蘭文、韓文等十幾種語言,在世界范圍內(nèi)產(chǎn)生了廣泛影響。
【譯者簡介】
陳德偉,深耕軟件研發(fā)十余年,目前專注于金融系統(tǒng)研發(fā)工作。
臧秀濤,InfoQ 前會議內(nèi)容總編,F(xiàn)于濤思數(shù)據(jù)負責開源時序數(shù)據(jù)庫 TDengine 的社區(qū)生態(tài)。代表譯作有《Java性能權(quán)威指南》《C API 設(shè)計》《Groovy 程序設(shè)計》等。
孫卓,現(xiàn)任職于百度健康研發(fā)中心,百度技術(shù)委員會成員。從業(yè)十余年,熟悉 Java、PHP 等語言體系,同時也是一名語言文字愛好者。
秦彬,現(xiàn)任騰訊游戲高級項目經(jīng)理,曾翻譯《體驗引擎》《游戲設(shè)計夢工廠》《游戲制作的本質(zhì)》等書。
第 1章 什么是對象 / 001
1.1抽象的歷程 / 002
1.2 對象具有接口 / 003
1.3 對象可以提供服務(wù) / 005
1.4 隱藏的實現(xiàn) / 006
1.5 復(fù)用實現(xiàn) / 008
1.6 繼承 / 008
is-a關(guān)系與is-like-a關(guān)系 / 012
1.7 多態(tài) / 013
1.8 單根層次結(jié)構(gòu) / 016
1.9 集合 / 017
參數(shù)化類型(泛型) / 018
1.10 對象的創(chuàng)建和生命周期 / 019
1.11 異常處理 / 021
1.12 總結(jié) / 022
第 2章 安裝Java和本書示例 / 023
2.1 編輯器 / 023
2.2 shell / 024
2.2.1 運行shell / 024
2.2.2 目錄(文件夾) / 025
2.2.3 shell基礎(chǔ)操作 / 025
2.3 安裝Java / 026
2.4 確認安裝成功 / 027
2.5 安裝和運行本書示例 / 028
Gradle基礎(chǔ)任務(wù) / 028
第3章 對象無處不在 / 029
3.1 通過引用操作對象 / 030
3.2 必須創(chuàng)建所有對象 / 031
3.2.1 數(shù)據(jù)保存在哪里 / 031
3.2.2 特殊情況:基本類型 / 032
3.2.3 Java中的數(shù)組 / 034
3.3 注釋 / 034
3.4 無須銷毀對象 / 035
3.4.1 作用域 / 035
3.4.2 對象的作用域 / 036
3.5 使用class關(guān)鍵字創(chuàng)建新類型 / 037
字段 / 037
3.6 方法、參數(shù)以及返回值 / 039
參數(shù)列表 / 039
3.7 編寫Java程序 / 041
3.7.1 名稱可見性 / 041
3.7.2 使用其他組件 / 042
3.7.3 static關(guān)鍵字 / 043
3.8 你的第 一個Java程序 / 045
編譯和運行 / 047
3.9 編程風格 / 048
3.10 總結(jié) / 049
第4章 操作符 / 050
4.1 使用Java操作符 / 050
4.2 優(yōu)先級 / 051
4.3 賦值 / 051
方法調(diào)用中的別名 / 053
4.4 算術(shù)操作符 / 054
一元加操作符和一元減操作符 / 055
4.5 自動遞增和自動遞減 / 056
4.6 關(guān)系操作符 / 057
測試對象是否相等 / 057
4.7 邏輯操作符 / 061
短路 / 062
4.8 字面量 / 063
4.8.1 字面量里的下劃線 / 065
4.8.2 科學記數(shù)法(又稱指數(shù)
記數(shù)法) / 066
4.9 按位操作符 / 067
4.10 移位操作符 / 067
4.11 三元操作符 / 071
4.12 字符串操作符 和 = / 072
4.13 使用操作符時常犯的錯誤 / 073
4.14 類型轉(zhuǎn)換操作符 / 074
4.14.1 截尾和舍入 / 075
4.14.2 提升 / 076
4.15 Java沒有sizeof() / 076
4.16 操作符小結(jié) / 076
4.17 總結(jié) / 081
第5章 控制流 / 082
5.1 true和false / 082
5.2 if-else / 083
5.3 迭代語句 / 084
5.3.1 do-while / 085
5.3.2 for / 085
5.3.3 逗號操作符 / 086
5.4 for-in語法 / 087
5.5 return / 089
5.6 break和continue / 090
5.7 臭名昭著的goto / 091
5.8 switch / 095
5.9 字符串作為選擇器 / 096
5.10 總結(jié) / 098
第6章 初始化和清理 / 099
6.1 用構(gòu)造器保證初始化 / 100
6.2 方法重載 / 102
6.2.1 區(qū)分重載的方法 / 103
6.2.2 使用基本類型的重載 / 104
6.2.3 通過返回值區(qū)分重載方法 / 107
6.3 無參構(gòu)造器 / 108
6.4 this關(guān)鍵字 / 109
6.4.1 在構(gòu)造器中調(diào)用構(gòu)造器 / 111
6.4.2 static的含義 / 112
6.5 清理:終結(jié)和垃圾收集 / 113
6.5.1 finalize()的作用 / 114
6.5.2 你必須執(zhí)行清理 / 115
6.5.3 終止條件 / 115
6.5.4 垃圾收集器的工作原理 / 117
6.6 成員初始化 / 120
指定初始化 / 121
6.7 構(gòu)造器初始化 / 122
6.7.1 初始化順序 / 123
6.7.2 靜態(tài)數(shù)據(jù)的初始化 / 124
6.7.3 顯式的靜態(tài)初始化 / 126
6.7.4 非靜態(tài)實例初始化 / 127
6.8 數(shù)組初始化 / 128
6.8.1 動態(tài)數(shù)組創(chuàng)建 / 129
6.8.2 可變參數(shù)列表 / 132
6.9 枚舉類型 / 136
6.10 新特性:局部變量類型
推斷 / 138
6.11 總結(jié) / 140
第 7章 實現(xiàn)隱藏 / 141
7.1 package:庫單元 / 142
7.1.1 代碼組織 / 144
7.1.2 創(chuàng)建獨一無二的包名 / 145
7.1.3 定制工具庫 / 148
7.1.4 用import來改變行為 / 149
7.1.5 關(guān)于包的忠告 / 150
7.2 Java訪問權(quán)限修飾符 / 150
7.2.1 包訪問 / 150
7.2.2 public:接口訪問權(quán)限 / 151
7.2.3 private:你無法訪問它 / 153
7.2.4 protected:繼承訪問權(quán)限 / 154
7.2.5 包訪問權(quán)限與公共構(gòu)造器 / 155
7.3 接口和實現(xiàn) / 156
7.4 類的訪問權(quán)限 / 157
7.5 新特性:模塊 / 160
7.6 總結(jié) / 162
第8章 復(fù)用 / 164
8.1 組合語法 / 165
8.2 繼承語法 / 167
初始化基類 / 169
8.3 委托 / 171
8.4 組合與繼承相結(jié)合 / 173
8.4.1 確保正確的清理 / 175
8.4.2 名稱隱藏 / 177
8.5 選擇組合還是繼承 / 178
8.6 protected關(guān)鍵字 / 180
8.7 向上轉(zhuǎn)型 / 181
再論組合與繼承 / 182
8.8 final關(guān)鍵字 / 182
8.8.1 final數(shù)據(jù) / 183
8.8.2 final方法 / 186
8.8.3 final類 / 188
8.8.4 關(guān)于final的忠告 / 189
8.9 初始化及類的加載 / 190
繼承與初始化 / 190
8.10 總結(jié) / 191
第9章 多態(tài) / 193
9.1 再論向上轉(zhuǎn)型 / 194
忘記對象類型 / 195
9.2 難點 / 196
9.2.1 方法調(diào)用綁定 / 197
9.2.2 產(chǎn)生正確的行為 / 197
9.2.3 可擴展性 / 201
9.2.4 陷阱:重寫private
方法 / 203
9.2.5 陷阱:字段與靜態(tài)方法 / 205
9.3 構(gòu)造器和多態(tài) / 206
9.3.1 構(gòu)造器的調(diào)用順序 / 206
9.3.2 繼承與清理 / 208
9.3.3 構(gòu)造器內(nèi)部的多態(tài)方法
行為 / 213
9.4 協(xié)變返回類型 / 215
9.5 用繼承進行設(shè)計 / 216
9.5.1 替換與擴展 / 217
9.5.2 向下轉(zhuǎn)型與反射 / 218
9.6 總結(jié) / 220
第 10章 接口 / 221
10.1 抽象類和抽象方法 / 221
10.2 接口定義 / 226
10.2.1 默認方法 / 228
10.2.2 多重繼承 / 230
10.2.3 接口中的靜態(tài)方法 / 233
10.2.4 作為接口的Instrument / 234
10.3 抽象類與接口 / 236
10.4 完全解耦 / 237
10.5 組合多個接口 / 242
10.6 通過繼承來擴展接口 / 244
組合接口時的名稱沖突 / 245
10.7 適配接口 / 246
10.8 接口中的字段 / 249
初始化接口中的字段 / 249
10.9 嵌套接口 / 250
10.10 接口和工廠 / 252
10.11 新特性:接口的private
方法 / 255
10.12 新特性:密封類和密封
接口 / 256
10.13 總結(jié) / 259
第 11章 內(nèi)部類 / 260
11.1 創(chuàng)建內(nèi)部類 / 261
11.2 到外部類的鏈接 / 262
11.3 使用.this和.new / 264
11.4 內(nèi)部類和向上轉(zhuǎn)型 / 266
11.5 在方法和作用域中的內(nèi)部類 / 267
11.6 匿名內(nèi)部類 / 269
11.7 嵌套類 / 273
11.7.1 接口中的類 / 274
11.7.2 從多層嵌套的內(nèi)部類中
訪問外部成員 / 275
11.8 為什么需要內(nèi)部類 / 276
11.8.1 閉包與回調(diào) / 278
11.8.2 內(nèi)部類與控制框架 / 281
11.9 繼承內(nèi)部類 / 287
11.10 內(nèi)部類可以被重寫嗎 / 287
11.11 局部內(nèi)部類 / 289
11.12 內(nèi)部類標識符 / 291
11.13 總結(jié) / 291
第 12章 集合 / 292
12.1 泛型和類型安全的集合 / 293
新特性:類型推斷和泛型 / 296
12.2 基本概念 / 297
12.3 添加一組元素 / 298
12.4 打印集合 / 300
12.5 List / 302
12.6 Iterator / 306
ListIterator / 309
12.7 LinkedList / 310
12.8 Stack / 312
12.9 Set / 314
12.10 Map / 318
12.11 新特性:記錄(record)
類型 / 321
12.12 Queue / 325
PriorityQueue / 327
12.13 Collection和Iterator的
對比 / 328
12.14 for-in和迭代器 / 332
適配器方法慣用法 / 334
12.15 總結(jié) / 338
第 13章 函數(shù)式編程 / 342
13.1 舊方式與新方式 / 344
13.2 lambda表達式 / 346
遞歸 / 348
13.3 方法引用 / 349
13.3.1 Runnable / 350
13.3.2 未綁定方法引用 / 351
13.3.3 構(gòu)造器方法引用 / 353
13.4 函數(shù)式接口 / 354
13.4.1 帶有更多參數(shù)的函數(shù)式
接口 / 361
13.4.2 解決缺乏基本類型函數(shù)
式接口的問題 / 361
13.5 高階函數(shù) / 363
13.6 閉包 / 364
內(nèi)部類作為閉包 / 369
13.7 函數(shù)組合 / 370
13.8 柯里化和部分求值 / 372
13.9 純函數(shù)式編程 / 373
13.10 總結(jié) / 374
第 14章 流 / 375
14.1 Java 8對流的支持 / 377
14.2 流的創(chuàng)建 / 378
14.2.1 隨機數(shù)流 / 379
14.2.2 int類型的區(qū)間范圍 / 382
14.2.3 generate() / 383
14.2.4 iterate() / 385
14.2.5 流生成器 / 385
14.2.6 Arrays / 386
14.2.7 正則表達式 / 387
14.3 中間操作 / 388
14.3.1 跟蹤與調(diào)試 / 389
14.3.2 對流元素進行排序 / 389
14.3.3 移除元素 / 390
14.3.4 將函數(shù)應(yīng)用于每個流
元素 / 390
14.3.5 在應(yīng)用map()期間組
合流 / 392
14.4 Optional類型 / 395
14.4.1 便捷函數(shù) / 397
14.4.2 創(chuàng)建Optional / 399
14.4.3 Optional對象上的操作 / 400
14.4.4 由Optional組成的流 / 404
14.5 終結(jié)操作 / 405
14.5.1 將流轉(zhuǎn)換為一個數(shù)組 / 405
14.5.2 在每個流元素上應(yīng)用某個終結(jié)操作 / 406
14.5.3 收集操作 / 407
14.5.4 組合所有的流元素 / 410
14.5.5 匹配 / 411
14.5.6 選擇一個元素 / 412
14.5.7 獲得流相關(guān)的信息 / 413
14.6 小結(jié) / 415
第 15章 異常 / 416
15.1 概念 / 417
15.2 基本的異常 / 418
異常參數(shù) / 419
15.3 捕捉異常 / 420
15.3.1 try塊 / 420
15.3.2 異常處理程序 / 420
15.4 創(chuàng)建自己的異常 / 421
異常與日志記錄 / 424
15.5 異常說明 / 427
15.6 捕捉任何異常 / 428
15.6.1 多重捕捉 / 430
15.6.2 棧軌跡 / 431
15.6.3 重新拋出異常 / 432
15.6.4 異常鏈 / 436
15.7 標準Java異常 / 439
特例:RuntimeException / 440
15.8 新特性:更好的NullPointerException
報告機制 / 441
15.9 使用finally執(zhí)行清理 / 443
15.9.1 finally是干什么用的 / 444
15.9.2 在return期間使用
finally / 446
15.9.3 缺陷:異常丟失 / 447
15.10 異常的約束 / 449
15.11 構(gòu)造器 / 452
15.12 try-with-resources語句 / 456
15.12.1 細節(jié)揭秘 / 459
15.12.2 新特性:try-with-resources中的實際
上的最終變量 / 463
15.13 異常匹配 / 464
15.14 其他可選方式 / 465
15.14.1 歷史 / 466
15.14.2 觀點 / 468
15.14.3 把異常傳遞到控制臺 / 470
15.14.4 將檢查型異常轉(zhuǎn)換為
非檢查型異常 / 470
15.15 異常使用指南 / 473
15.16 小結(jié) / 473
附記 異常的奇異世界 / 474
第 16章 代碼校驗 / 476
16.1 測試 / 476
16.1.1 單元測試 / 477
16.1.2 測試覆蓋率的幻覺 / 481
16.2 前置條件 / 482
16.2.1 斷言 / 482
16.2.2 DbC 單元測試 / 488
16.2.3 使用Guava里的前置
條件 / 495
16.3 測試驅(qū)動開發(fā) / 498
測試驅(qū)動與測試優(yōu)先 / 505
16.4 日志 / 505
日志級別 / 507
16.5 調(diào)試 / 508
16.5.1 使用JDB進行調(diào)試 / 508
16.5.2 圖形調(diào)試器 / 511
16.6 基準測試 / 511
16.6.1 微基準測試 / 512
16.6.2 介紹JMH / 514
16.7 分析與優(yōu)化 / 520
優(yōu)化指南 / 520
16.8 樣式檢查 / 521
16.9 靜態(tài)錯誤分析 / 521
16.10 代碼審查 / 521
16.11 結(jié)對編程 / 522
16.12 重構(gòu) / 522
重構(gòu)的基礎(chǔ) / 522
16.13 持續(xù)集成 / 523
16.14 總結(jié) / 525
第 17章 文件 / 526
17.1 文件和目錄路徑 / 527
17.1.1 選擇Path的片段 / 530
17.1.2 分析Path / 531
17.1.3 添加或刪除路徑片段 / 532
17.2 目錄 / 533
17.3 文件系統(tǒng) / 537
17.4 監(jiān)聽Path / 538
17.5 查找文件 / 541
17.6 讀寫文件 / 543
17.7 小結(jié) / 546
第 18章 字符串 / 547
18.1 不可變的字符串 / 547
18.2 重載 與StringBuilder / 548
18.3 無意識的遞歸 / 553
18.4 對字符串的操作 / 555
18.5 格式化輸出 / 556
18.5.1 printf() / 556
18.5.2 System.out.format() / 557
18.5.3 Formatter類 / 557
18.5.4 格式說明符 / 558
18.5.5 Formatter轉(zhuǎn)換 / 560
18.5.6 String.format() / 562
18.6 新特性:文本塊 / 563
18.7 正則表達式 / 565
18.7.1 基礎(chǔ) / 566
18.7.2 創(chuàng)建正則表達式 / 569
18.7.3 量詞 / 571
18.7.4 Pattern和Matcher / 572
18.7.5 split() / 580
18.7.6 替換操作 / 580
18.7.7 reset() / 582
18.7.8 正則表達式和Java
I/O / 583
18.8 掃描輸入 / 584
18.8.1 Scanner分隔符 / 586
18.8.2 使用正則表達式掃描 / 586
18.9 StringTokenizer / 587
18.10 總結(jié) / 588
第 19章 反射 / 589
19.1 為什么需要反射 / 589
19.2 Class對象 / 592
19.2.1 類字面量 / 596
19.2.2 泛型類的引用 / 598
19.2.3 cast()方法 / 602
19.3 轉(zhuǎn)型前檢查 / 603
19.3.1 使用類字面量 / 609
19.3.2 動態(tài)的instanceof / 611
19.3.3 遞歸計數(shù) / 612
19.4 注冊工廠 / 614
19.5 Instanceof與Class的
等價性 / 616
19.6 運行時的類信息 / 618
類方法提取器 / 619
19.7 動態(tài)代理 / 621
19.8 使用Optional / 625
19.8.1 標簽接口 / 630
19.8.2 模擬對象和樁 / 633
19.9 接口和類型信息 / 633
19.10 總結(jié) / 639
第 20章 泛型 / 641
20.1 和C 的對比 / 642
20.2 簡單泛型 / 643
20.2.1 元組庫 / 645
20.2.2 棧類 / 648
20.2.3 RandomList / 649
20.3 泛型接口 / 650
20.4 泛型方法 / 653
20.4.1 可變參數(shù)和泛型方法 / 654
20.4.2 通用Supplier / 655
20.4.3 簡化元組的使用 / 657
20.4.4 Set實用工具 / 658
20.5 構(gòu)建復(fù)雜模型 / 663
20.6 類型擦除的奧秘 / 665
20.6.1 C 的實現(xiàn)方法 / 667
20.6.2 遷移的兼容性 / 669
20.6.3 類型擦除存在的問題 / 670
20.6.4 邊界的行為 / 672
20.7 對類型擦除的補償 / 676
20.7.1 創(chuàng)建類型實例 / 677
20.7.2 泛型數(shù)組 / 680
20.8 邊界 / 686
20.9 通配符 / 689
20.9.1 編譯器有多聰明? / 692
20.9.2 逆變性 / 694
20.9.3 無界通配符 / 696
20.9.4 捕獲轉(zhuǎn)換 / 705
20.10 問題 / 707
20.10.1 基本類型不可作為
類型參數(shù) / 707
20.10.2 實現(xiàn)參數(shù)化接口 / 709
20.10.3 類型轉(zhuǎn)換和警告 / 709
20.10.4 重載 / 712
20.10.5 基類會劫持接口 / 712
20.11 自限定類型 / 714
20.11.1 奇異遞歸泛型 / 714
20.11.2 自限定 / 715
20.11.3 參數(shù)協(xié)變性 / 718
20.12 動態(tài)類型安全 / 721
20.13 異常 / 722
20.14 混型 / 724
20.14.1 C 中的混型 / 724
20.14.2 與接口混合 / 726
20.14.3 使用裝飾器模式 / 727
20.14.4 與動態(tài)代理混合 / 729
20.15 潛在類型機制 / 730
20.15.1 Python中的潛在類型
機制 / 731
20.15.2 C 中的潛在類型
機制 / 732
20.15.3 Go中的潛在類型
機制 / 733
20.15.4 Java中的直接潛在
類型機制 / 735
20.16 對于缺少(直接的)潛在類型機制的補償 / 736
20.16.1 反射 / 736
20.16.2 將方法應(yīng)用于序列 / 737
20.17 Java 8中的輔助潛在類型
機制 / 741
使用Supplier的泛型方法 / 743
20.18 總結(jié):轉(zhuǎn)型真的這么糟糕嗎? / 745
延伸閱讀 / 747
第 21 章 數(shù)組 / 748
21.1 數(shù)組為何特殊 / 749
一個用于顯示數(shù)組的常用工具
程序 / 751
21.2 數(shù)組是一等對象 / 752
21.3 返回數(shù)組 / 755
21.4 多維數(shù)組 / 757
21.5 數(shù)組和泛型 / 761
21.6 Arrays.fill() / 764
21.7 Arrays.setAll() / 765
21.8 增量生成器 / 766
21.9 隨機數(shù)生成器 / 775
21.10 泛型和基本類型數(shù)組 / 783
21.11 修改已有的數(shù)組元素 / 787
21.12 關(guān)于數(shù)組并行 / 788
21.12.1 策略 / 789
21.12.2 parallelSetAll() / 789
21.13 數(shù)組實用工具 / 790
21.14 數(shù)組復(fù)制 / 791
21.15 數(shù)組比較 / 794
21.16 流和數(shù)組 / 795
21.17 數(shù)組排序 / 796
21.17.1 使用Arrays.sort() / 800
21.17.2 并行排序 / 801
21.18 用Arrays.binarySearch()進行二分查找 / 802
21.19 用parallelPrefix()進行累積計算 / 804
21.20 總結(jié) / 806
補充內(nèi)容 / 809
積極看待C 與Java的
遺產(chǎn) / 810