你好,我们是Duncan和Nat。当你阅读这篇前言的时候,你可能正在考虑是否要花费几小时来阅读本书的剩余部分。那就让我们开门见山:
本书不会教你如何使用Kotlin编写代码。
我们原本打算写一本这样的书,但很快就想到Kotlin是一门大型语言,撰写一本这样的书的时间会比我们想象中要长。此外,这个领域已经有一些很棒的书籍,我们不想与它们竞争。
因此我们决定让事情更简单,只聚焦于教授Java开发人员如何使用Kotlin,并通过一个名为“重构为Kotlin”的工作坊来进行教学。也就是说,通过转化现有Java代码来教授Kotlin语言,是为了那些希望利用现有知识快速普及Kotlin的Java团队量身定制的。然后我们着手写这样一本书,但很快又想到Kotlin仍然是一门大型语言,我们仍需要很长的时间来撰写。我们还发现,有积极性和资深的Java开发人员可以很快掌握Kotlin的大部分知识。在语言特征上进行深耕可能会获得目标读者的赞赏,但这样显得有点自诩清高。于是我们放弃了这个想法,所以:
本书不会教你Kotlin语言。
那么,为什么你要读这本书呢?因为我们写了一本在我们初次接触Kotlin时希望拥有的书。我们都是资深的程序员,熟知Java以及Java生态。我们希望你也是。和我们一样,你可能在其他几种语言上也有经验。你已经掌握了Kotlin的基本知识,知道要充分利用这门语言,需要用不同的方式设计你的系统。你发现在Kotlin中,有些事情比Java简单得多,有些功能(如受检异常)根本就不存在。你不想仅仅是采用Kotlin的语法来编写Java代码。
你可能身处技术领导职位,或者已经成功说服了团队采用Kotlin。为了让项目采用Kotlin,你可能花费了一些成本。现在你需要确保转型顺利进行。
你可能负责一个Java代码库,希望确保引入Kotlin不会破坏现有的关键业务代码。或者你可能从零开始一个Kotlin项目,但意识到你的设计灵感更倾向于Java和对象,而不是Kotlin和函数。
如果你身处这样的境地,那么你找对了地方。这本书将帮助你调整思维和设计,以充分利用Kotlin。然而这还不够,因为你需要维护和改进现有的代码。所以我们还展示了如何使用IntelliJ IDE中内置的自动重构工具逐步且安全地从Java语法迁移到Kotlin语法,并从Java思维转变到Kotlin思维。
本书的组织方式
本书讲的是如何从Java过渡到Kotlin,主要关注代码,但也涉及项目和组织。每章都讲述了从Java过渡到Kotlin的某个方面,以及典型Java项目在这个过程中可以改进的某个方面。多数章节都是以“从Java方式到Kotlin方式”这种模式命名的,我们建议你选择后者而不是前者。这可能是因为Kotlin使Java中很难实现的方法变得更容易,或者是因为Kotlin规避了Java中常见的方法,以引导设计向更少的错误、更简洁和工具更友好的方向前进。
我们不仅仅建议你采用Kotlin方式,相关章节还展示了如何进行转换。我们不仅仅是重写Java,还通过安全的方式逐步重构为Kotlin方式,并允许维护混合语言代码库。
我们是如何挑选主题的
我们首先分析了Java和Kotlin开发人员对各自语言的使用情况,并进行了采访,以确定两种语言的差异和混淆之处。这是通过对33459个开源的Java和Kotlin代码库进行机器学习分析得到的结果。这些分析帮助确定了候选主题,我们用“从什么到什么”的形式标记候选主题,然后根据频率和开发人员痛点系数对其进行排序,以确定应该选择哪些主题。最后,我们根据“……”对剩下的主题进行排序。在这里用“……”不太好,但我们不能对你撒谎。事实上,我们从一开始就选择了想写的主题,我们认为这些主题会有趣且有益。第9章、第15章、第20章都是典型的例子。我们还寻找了Kotlin和Java差异显著的地方,通过思考它们之间为何不同,我们发现这是我们学到东西最多的地方。这导致了第4章、第6章、第8章等章节的产生。
在撰写这些章节时,其他主题也自然而然地出现在候选名单上。特别是,在我们为某一章编写重构步骤时,我们经常发现自己对代码进行了一些改动,我们认为这些改动值得单独成章。第10章、第11章、第13章就是这方面的例子。
这个过程产生的结果绝不是详尽无遗的。如果你已经翻阅过目录,你会发现有一些重要的主题并没有提及。以协程(协同程序)为例:这里是本书唯一提及这个庞大主题的地方,因为我们发现协程并没有改变我们编写服务器端代码的方式,所以我们不想写关于它的任何内容。如果有空间和时间的话,我们还希望涉及以下主题:构建器、领域特定语言、反射、依赖注入框架、事务……
我们希望我们所写的主题是你感兴趣的。这本书主要是关于战术而不是战略的,关注的是我们可以赢得的“小战斗”,而不是整个部门可以达成的大目标。随着更大的主题浮现出来,我们会试着将它们串联起来,并在最后一章(第23章)把事情归结在一起,谈论我们在写作过程中学到的东西。
复杂度
如何评估软件的内部质量?假设我们的软件能够满足客户的需求,如何比较两种潜在的实现方案,或者评判一项变更是使软件更好还是更差?我们的答案是复杂度。在其他条件相同的情况下,我们偏爱简单的设计,这种设计可以产生可预测的行为。
当然,在某种程度上,简单和复杂是因人而异的。我们有略微不同的个人喜好,所以有时会在某个实现方案是更好还是更差的问题上存在分歧。在这种情况下,我们会在相关章节中探讨替代方案。然而,我们都相信函数式编程可以降低系统的复杂度,特别是与面向对象(O O)的消息传递结合使用时。
多年来,Java一直在朝着这个方向发展。Scala则朝着函数式编程的方向发展,但远离了OO。我们发现Kotlin的编程方式可以让我们以一种混合函数式编程和面向对象编程的方式来降低复杂度,让普通开发人员发挥出最佳水平。
完美代码
以大众的视角,我们应该关注代码质量。我们很想追求代码的完美,因为我们知道你可能会根据代码来评价我们,像众多开发人员一样,我们的自尊心与我们的产出质量息息相关。
但是,我们是工程师而不是艺术家。我们的工作是为客户平衡范围、进度和成本,除非代码的质量影响到这三个更高的价值,否则没有人真正关心它。
因此在示例中,我们尽量展示真实的生产代码。起点的代码有时不太好,因为毕竟我们还想展示如何改进它们。通常重构会先让事情变得更糟,然后才会变得更好,所以绝不要根据各章中间的代码来评价我们。在一章结束时,我们的目标是拥有足够好的代码,但不是完美到让我们被指责浪费了客户的钱。
话虽如此,我们有一个策略,即在完成了既定的主题后,应用一些有成效的变更来整理代码,有时候甚至会拓展出一个新的主题,并撰写一章来使代码达到我们满意的状态。最终,我们既是工程师又是艺术家。
代码格式
我们的代码尽可能地遵循Java和Kotlin的标准编码规范。
书中示例代码的实际行长度比我们在IDE中通常设置的120个字符要短得多,因此,我们需要更频繁地拆分代码行,使其适应页面宽度。我们的生产代码可能在一行上有四五个变量或参数,但在本书中,我们通常只有一个参数。通过格式化示例代码来适应版面,我们渐渐喜欢上了这种更加纵向的样式。我们发现,Kotlin自然地倾向于占用更多的垂直空间,即便是Java,也可以通过缩短行、增加换行和更多的可视化对齐来提高代码的可读性。像书籍一样,在IDE中进行水平滚动也不方便,我们在结对环节通过减少滚动和增加并排窗口来加以改进。每个参数单独一行也能大大提高代码版本之间的差异对比效率。我们希望它读起来至少不会让你感到痛苦,如果你不这么觉得,那么可以尝试在自己的代码中应用这种风格。
有时我们会隐藏与讨论无关的代码。以3个点的省略号开头的行表示出于清晰或简洁的目的省略了一些代码。例如:
排版约定
本书中使用以下排版约定:
斜体( Itali c)
表示新的术语、URL、电子邮件地址、文件名和文件扩展名。
等宽字体(Constant width)
用于程序清单,以及段落中的程序元素,例如变量名、函数名、数据库、数据类型、环境变量、语句以及关键字。
该图示表示提示或建议。
该图示表示一般性说明。
该图示表示警告或注意。
示例代码
本书中的大多数示例代码(来自重构部分的示例代码)可以在GitHub上在线访问。代码后面附有参考链接,例如:
如果你正在阅读本书的电子版,参考链接应该是指向GitHub上该文件版本的超链接。如果在纸质书上点击链接,则没有反应。但如果你将示例编号(此例中为0.1)输入本书网站( https://java-to-kotlin.dev/code.html )的表单中,将带你转到相同位置的链接。
在Git中,不同的示例代码(有时跨越多个章节)会在不同的分支中演进。步骤会被标记,例如,这里table-reader.1是标记。GitHub链接指向具有该标记的代码,因此你可以在该版本中查看所示文件(此处为 src/test/java/travelator/tablereader/TableReader-AcceptanceTests.kt )以及示例的其他内容。你还可以选择其他标记以查看不同的版本,选择不同的分支以查看不同的示例。为了更快地导航,你可以克隆代码存储库,在IntelliJ中打开它,并使用Git工具窗口切换分支和版本。
示例代码并不是真实的!代码库可以构建并通过测试,但它是虚构的。
可以访问 https://java-to-kotlin.dev 询问技术问题。
这里的代码是为了帮助你更好地理解本书的内容。通常,可以在程序或文档中使用本书中的代码,而不需要获得许可,除非需要大段地复制代码。例如,使用本书中所提供的几个代码片段来编写一个程序不需要得到我们的许可,但销售或发布本书的示例代码则需要获得许可。引用本书的示例代码来回答问题也不需要许可,将本书中的很大一部分示例代码放到自己的产品文档中则需要获得许可。
非常欢迎读者使用本书中的代码,希望(但不强制)注明出处。注明出处时包含书名、作者、出版社和ISBN,例如:
Java to Kotlin,作者Duncan McGregor和Nat Pryce,由O’ Reilly出版,书号978-1-492-08227-9
如果读者觉得对示例代码的使用超出了上面所给出的许可范围,欢迎通过 permissions@oreilly.com 联系我们。
O ' Reilly在线学习平台(O ' Reilly Online Learning)
40多年来,O'Reilly Media致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。
我们拥有独一无二的专家和革新者组成的庞大网络,他们通过图书、文章、会议和我们的在线学习平台分享他们的知识和经验。O Reilly的在线学习平台允许你按需访问现场培训课程、深入的学习路径、交互式编程环境,以及O Reilly和200多家其他出版商提供的大量文本和视频资源。有关的更多信息,请访问 http://oreilly.com 。
如何联系我们
对于本书,如果有任何意见或疑问,请按照以下地址联系本书出版商。
美国:
中国:
北京市西城区西直门南大街2号成铭大厦C座807室(100035)
奥莱利技术咨询(北京)有限公司
要询问技术问题或对本书提出建议,请发送电子邮件至 bookquestions@oreilly.com 。
本书配套网站 https://oreil.ly/java-to-kotlin 上列出了勘误表、示例以及其他信息。
关于书籍、课程、会议和新闻的更多信息,请访问我们的网站 http://www.oreilly.com 。
我们在Facebook上的地址: http://facebook.com/oreilly
我们在Twitter上的地址: http://twitter.com/oreillymedia
我们在YouTube上的地址: http://youtube.com/oreillymedia
致谢
感谢Hadi Hariri向O Reilly建议我们写这本书,感谢Zan McQuade听从他的建议。感谢我们的编辑Sarah Grey,以及Kerin Forsyth和Kate Galloway整理所有内容。
感谢许多朋友和同事,以及一些可爱的陌生人,他们审查了各种版本的草稿。感谢Yana Afanasyeva、Jack Bolles、David Denton、Bruce Eckel、Dmitry Kandalov、Kevin Peel、James Richardson、Ivan Sanchez、Jordan Stewart、Robert Stoll、Christoph Sturm、Lukasz Wycisk、Daniel Zappold,以及我们的技术审稿人Uberto Barbini、James Harmon、Mark Maynard和Augusto Rodriguez。我们非常感谢他们提供的所有建议和对我们的鼓励。
极限编程革命性地改变了我们编写软件的方式,我们都应该感谢Ward Cunningham和Kent Beck。同时也要感谢Martin Fowler,如果没有他,可能不会有这本书。在英国,自1999年以来,极限星期二俱乐部一直在极限编程想法上进行创新,并吸引了一批开发人员。我们很幸运地与这个小组中许多才华横溢的成员一起工作和学习。如果你有问题,如果没有其他人可以帮到你,如果你能找到他们,也许你可以与他们一起工作。
Duncan的致谢
我的妻子Jo McGregor不了解我的工作内容,也不会读完这本书,但她可能会读到这部分。因此,感谢她忍受我写作而不是陪伴她,以及在我陪伴她时仍在谈论写作。没有她的支持和鼓励,我无法完成这本书。还要感谢我们的两个儿子Callum和Alistair,他们让我们非常自豪。
感谢我的母亲Vickie Kennish对我的写作表现出浓厚的兴趣,她在我们散步时经常询问进展情况。我已故的父亲John肯定会装作不在意,但会向他的朋友炫耀这本书。我们漂亮的猫Sweet Pea已经离开了,但它不会被遗忘,它在我写作过程中一直陪伴着我,只是在书完成之前去世了。
Robin Helliwell的友谊和支持一直伴随着我,还有我的姐姐Lucy Seal和许多其他家庭成员。在我的职业生涯中,除了那些提供反馈的人之外,还要感谢Alan Dyke、Richard Care和Gareth Sylvester-Bradley,他们都对我有很大的影响。
Nat的致谢
当我告诉我的妻子Lamaan我计划写这本书时,她的第一反应并不是惊恐。因此,我要非常感谢她的鼓励和支持。
感谢我的妹妹Lois Pryce和妹夫Austin Vince,书中的示例代码受到他们的摩托车旅行、书籍和电影的启发。
还要感谢Oliver和Alex。现在这本书已经完成,我又可以提供音乐和游戏编程咨询服务了。