当前位置: 首页 > 科技观察

Kotlinvs.Java:谁更好?

时间:2023-03-12 10:29:40 科技观察

KotlinKotlin是JetBrains自2011年以来一直在积极开发的一种相对较新的JVM语言。多年来,该语言在Android社??区中越来越受欢迎,并在GoogleIO2017大会之后成为Android开发中最热门的话题。大会宣布Android正式支持Kotlin。遗憾的是,虽然关于Kotlin的文章很多,但客观信息并不多,许多开发人员仍在怀疑迁移到Kotlin是否是正确的道路。在本文的其余部分,我将尝试提供一份更完整的清单,列出在评估Kotlin作为Java替代品时需要考虑的事项。Kotlin和Java的主观比较“Kotlin比Java好”,“Kotlin比Java可读性强”,“Kotlin开发速度比Java快”,这样的说法缺乏相关准确数据的支持,所以都是主观的种类。主观意见是个体开发者在对与Kotlin或Java相关的话题做出一个或多个主观判断时形成的。开发者的主观判断存在以下问题:没有与主观判断相关联的量化指标。主观判断存在很大的偏差。开发人员之间的判断偏见差异很大。由于没有与主观判断相关的定量指标,因此基于这些判断的意见仅反映了开发人员先前存在的偏见。不同的开发人员可能有截然不同的偏见,因此仅仅因为一个开发人员认为Kotlin是一个好的(或坏的)Java替代品并不意味着其他开发人员也有同样的想法。而且,由于没有客观指标,客观上无法消除主观差异,往往会引发“口水战”。主观判断的谬误为了说明主观判断如何导致误解,让我们仔细看看一个非常普遍的主观信念:Kotlin比Java更具可读性——网络上的文章数不胜数理论上,人们可以尝试设计一个指标来衡量衡量Kotlin和Java之间的可读性差异的实验,但据我所知,还没有人真正进行过这样的实验。因此,截至目前,这种观点还没有任何数据支持。Kotlin的语法是许多开发人员称赞其可读性的原因之一。他们的逻辑是这样的:Kotlinhasabettersyntax,soitismorereadable——网络上无数文章都在说这句话,“bettersyntax”又是一个主观判断,本身就值得商榷,但是为了避免争论,我们假设Kotlin的语法确实更好。然而,这是否意味着Kotlin更具可读性?观察句法对可读性的影响,请阅读这段“文字”:起初,这段“文字”很难看懂,但慢慢地,就会越来越容易阅读。如果你读两三遍,你甚至不会注意到它是由非标准字母组成的。字母的替换并不完全是语法上的变化,但它确实说明外观很少会妨碍熟练读者的可读性。我们也可以将这个例子扩展到自然语言。我知道三种截然不同的语言。虽然它们差异很大,但我发现当我不理解文本中使用的单词时,很难阅读任何一种语言的文本。一旦我认出了构成文本的单词并理解了上下文——无论它是什么语言——我都可以毫不费力地阅读它。所以,对我来说,语言的选择不会影响可读性,它只是关于理解内容和上下文。编程语言也是如此。当我们开始使用一门新的语言时,我们会一时难以理解源代码,需要仔细理解每一个句法结构。然而,随着我们阅读和编写越来越多的特定语言的代码,我们逐渐熟悉该语言的语法,并且在某些时候,我们不再关注语法结构。我自己用几种语言完成了这项工作:Verilog、Bash、Perl、Tcl、Lisp、Java。根据我对上述语言的经验,我可以告诉你:如果一个人适应了Lisp的代码并且不再注意到括号,那么与Java相比,Kotlin的语法对可读性的影响是不可忽略的。影响,即使它“更好”。既然进入正题,我就分享一下我对影响源码可读性因素的主观判断。在阅读了其他开发者用多种语言编写的代码后(以上只是我在某个阶段精通的语言列表;我使用的语言比这更多),我得出以下结论:如果一个开发者使用某种语言能够写出易读易懂的代码,往往也可以用其他语言写出易读易懂的代码。因此,我根据自己的经验主观判断源代码的可读性与选择的语言无关,它取决于代码编写者的技能和读者的技能(编写者的技能更重要的)。如果您仍然认为主观意见具有代表性,至少请阅读并思考Robert“UncleBob”Martin在这篇博文中的观点。客观的Kotlin与Java比较与主观比较相反,主观比较使用定量指标来衡量或评估Kotlin优于Java的地方。用一套标准来客观地证明一种编程语言是否优于另一种编程语言的想法非常吸引人,但有一个问题:据我所知,目前还没有一个与编程语言相关的通用客观指标。鉴于我们不能做一个准确的直接比较,我们能否客观地比较Kotlin和Java?是的!我们仍然可以评估从Java切换到Kotlin的积极影响和信息影响的程度,然后比较结果,并讨论它们的影响。为了评估Kotlin能够带来的最佳效果,我们将做出以下假设:开发者可以立即切换到Kotlin;开发人员在转用Kotlin后不会失去任何技能(例如,有两年Java开发经验的开发人员可以神奇地获得两年的Kotlin开发经验);Kotlin和Java一样稳定;Kotlin工具和Java工具一样成熟。其实,以上假设都不是合理的,只是开头有一个理想化的设定来说明。然后我们搁置这些假设并讨论现实世界影响的含义。Kotlin***ResultsEstimation遵循SteveMcConnell在CodeComplete一书中提出的模式,我们可以将软件构建活动分解为三个子活动:详细设计、编码和调试以及开发测试。Kotlin对详细设计子活动(通常与选择的具体面向对象编程语言无关)的影响很小,因此在这部分,Kotlin和Java需要付出同样的努力。据我所知,Kotlin也没有为开发测试子活动提出任何革命性的东西。因此,开发测试需要付出同样的努力。剩下的就是对子活动进行编码和调试。如果我们用Kotlin替换Java,我可以在编码和调试活动中节省多少精力?这个问题很难回答,这个值在不同的程序员之间会有很大的差异(有些程序员使用Java效率更高)。但是,由于我们正在评估***场景,让我们假设在编码和调试阶段从Java切换到Kotlin会使开发人员的工作效率平均提高10%。生产率提高10%是一个非常不现实的数字。即使我们在文本编辑器中手动键入所有代码,那也是不现实的。考虑到当今IDE的功能,这个数字就更不现实了。考虑到一些开发人员使用Java的效率更高,这个数字毫无意义。我不介意使用这样一个既不切实际又对Kotlin评估有利的值,因为我知道无论它对评估结果有多么不切实际的正面影响,一旦我们丢弃其中一些“理想假设”,得到的结果就是负面的影响将抵消这些积极影响。那么,编码和调试方面提高10%——我们向客户交付产品的速度提高了多少?下图来自CodeComplete一书,显示了软件项目中各种活动的百分比:小型项目以构建活动为主。更大的项目需要更多的架构、集成和系统测试工作来确保项目成功。此图未显示需求,因为与其他活动不同,需求工作不是直接的程序功能。(Albrecht1979年;Glass1982年;Boehm、Gray和Seewaldt1984年;Boddie1987年;Card1987年;McGarry、Waligora和McDermott1989年;Brooks1995年;Jones1998年;Jones2000年;Boehm等人2000年)代码完整,第2版根据对于这张来自CodeComplete的图片,在一个更大的软件项目(超过10K行)中,编码和调试只占项目总工作量的不到20%。因此,在更大的软件项目中,我们假设编码和调试效率提高10%只会将完成项目所需的总工作量减少2%。比如一个需要5man-year完成的项目(这是一个比较大的Android项目),2%的总工作量就是:5man-years*12*4*5*0.02=24(man-days)如果我们真的可以将项目工作量减少24个工作日,那将是从Java切换到Kotlin的一个很好的理由。然而,我们应该记住,上述积极评估是基于基于理想情况的不切实际的假设。我们将评估切换到另一种编程语言在现实世界中不可避免的影响,并将其与上述理想化评估进行比较。开发人员准备情况为了评估最佳情况,我们假设开发人员可以立即从Java切换到Kotlin。事实上,虽然Kotlin与Java非常相似,但开发者仍然需要时间去学习,然后再花一些时间来调整开发实践和工具。准备时间各不相同:一些开发人员可以在三四天内完成转换,而其他开发人员可能需要10天或更长时间。让我们保持乐观,普通开发人员可以在短短5天内从Java切换到Kotlin。一个需要5人年才能完成的项目将有3到5个开发人员(***案例)。每个开发人员的平均切换时间为5天,因此一个项目总共需要15到25人天的切换时间。切换到Kotlin节省的工作量(乐观估计)似乎与切换所需的总工作量大致相同。开发人员技能丧失使用特定编程语言有效工作的能力是一种技能。我们已经讨论了此技能的一个方面(代码可读性),但还有许多其他方面。当从一种语言切换到另一种语言时,与旧编程语言相关的一些技能可以转移到新语言中,但其他部分技能会丢失。为了评估编程语言技能损失对项目工作量的影响,我们将使用源自Cocomo2评估模型的“语言和工具体验”因素:语言和工具体验(LTEX)该指标用于衡量开发软件系统的项目或子系统团队在编程语言和软件工具方面的经验。软件开发包括使用工具完成需求、表示设计和分析、配置管理、文档提取、库管理、程序风格和格式、一致性检查、计划和控制等。除了对项目的编程语言有经验外,经验项目的配套工具集也会影响开发工作。少于2个月的经验会得到很低的评价,6个月或以上的经验会得到很高的评价,见下表:Cocomo2ModelDefinitionManual例如,假设我们有一个Java开发团队,Team成员平均有一年的经验,我们想迁移到Kotlin。由于Kotlin与Java非常相似,因此它与许多Java工具兼容。我们可以乐观地假设,在初步准备之后,开发人员可以归类为具有6个月的开发经验(而不是少于2个月)。基于此假设,要评估由于技能损失而导致的额外工作量,项目的名义工作量应乘以1.09。在一个耗时5人年才能完成的项目中,开发人员平均拥有1年的Java经验,切换到Kotlin导致了惊人的108人日的额外工作。由于技能损失而导致的额外工作量是切换到Kotlin所减少的工作量的四倍。语言和工具的稳定性和成熟度人们普遍认为Kotlin是一种生产就绪语言。这种说法可能是有道理的,因为Kotlin已经在几个项目中使用。然而,与Java相比,Kotlin是一门年轻且不稳定的语言。一些开发人员将Kotlin的不稳定性视为一个优势——该语言不断发展,更快地提供新功能,并更快地改进。在我看来,他们对此事的看法过于简单化了。这是Kotlin1.1.4发行说明(撰写本文时的最新版本)的第一句话:FixingamajorperformanceregressioninIntelliJIDEA-Kotlin1.1.4releasenotesIdidn'tknowitwhatkindofrecession,有多少项目受到影响,但我的大脑自动将“主要性能回归”配对翻译为“浪费了许多小时的开发时间”。此外,如果您通读发行说明的评论,您会注意到很多人都遇到迁移问题。在1.1.2版的评论中,甚至有人指出这个“补丁”版本引入了破坏性的(向后不兼容的)变化。相比之下,如果你仔细阅读了OracleJDK8的releasenotes,你会发现它是比较稳定的。大多数修改都是安全改进。因此,与Java相比,Kotlin是一种不稳定且不成熟的语言——迁移到Kotlin将如何影响项目?为了回答这个问题,我将使用Cocomo2评估模型WorkFactor中的“PlatformVolatility”:PlatformVolatility(PVOL)这里使用术语“平台”来指代复杂的硬件和软件(操作系统、DBMS等)。)软件产品调用来执行任务。如果正在开发的软件是操作系统,那么平台就是计算机硬件。如果您正在开发数据库管理系统,那么平台就是硬件和操作系统。如果您正在开发Web文本浏览器,那么平台就是网络、计算机硬件、操作系统和分布式信息存储库。平台包括支持软件系统开发所需的编译器或汇编器。如下表所示,如果平台每12个月只有一次重大变化,则评级较低,如果每2周发生一次重大变化,则评级较高:Cocomo2ModelDefinitionManualYoumayhave注意到,编程语言并没有直接出现在工作因素的描述中,而是出现了编译器和汇编器。在我看来,这个描述并没有明确包括编程语言,因为所有导致Cocomo2模型的项目都使用稳定的语言。由于编译器和汇编器属于这个工作因素,我们也可以推断出编程语言和相关工具。根据这种平台波动性评级等级,Java应被评为“非常低”,而Kotlin应被评为“低”或更高。由于Kotlin对其他工具的内部依赖性增加了兼容性问题的风险,因此它的评级可能更高。由于“非常低”不提供工作因数,因此我们需要进行估算。从这个因素的分数从“非常高”到“低”的递减规律来看,我认为我们可以有把握地假设“非常低”的分数不高于0.82。基于这些假设(有利于Kotlin),如果一个项目名义上需要5人年的工作量,那么Kotlin的工作量为1044人日,Java的工作量为984人日。选择在Kotlin而不是Java中实施这样的项目将增加60个工作日的总工作量。由于语言和工具不稳定而导致的额外工作量是切换到Kotlin所减少工作量的2倍多。考虑到所有因素,我作为示例讨论的项目需要5人年的名义努力。根据以上评估,如果项目由平均1年Java开发经验的开发人员用Java实现,总工作量为:man-year*LTEX(Java)*PVOL(Java)=984(man-day)如果相同的项目由没有Kotlin开发经验的开发者使用Kotlin实现,总工作量为5man-years*LTEX(Kotlin)*PVOL(Kotlin)*0.98+T_ramp_up=1115+5*N_developers(man-day)选择Kotlin而不是Java所造成的额外工作量估计为131+5*N_developers(人日)。评估注意事项在评估讨论中,我们提出了与Kotlin和Java相关的方便的单点努力值。但实际上,单点值根本不是估计值——它们只是猜测。真实的估计必须具有相关的不确定性。换句话说,估计值代表一系列可能性,而不是单个点值。我们最终使用单点值而不是范围,那是因为我从估计范围中选择了对Kotlin最有利的值,并将所有估计值转换为单点值。例如,在讨论Kotlin对编码和调试活动的影响时,我从估计的可能性范围[-5%,10%]中选择了10%的最佳生产力增益。在其他情况下,当我们讨论开发人员切换到Kotlin的平均时间时,我从估计的可能性范围[5天,21天]中选择了最小的5天。此外,我们还使用了Cocomo2估计模型特有的工作因数。这些因素不是普遍真理,在大多数一般情况下应该存在相关的不确定性。我给Kotlin的评价比我认为它应得的要高,我希望通过这种方式消除这种不确定性。不用说,我们得到的单点值并不是绝对正确的。为了获得更完整的估计,我们可以使用真实估计运行蒙特卡罗模拟。使用这种技术,我们可以查看可能结果的分布,并找出最有可能发生的结果。请记住,其他可能的结果显示更大的Kotlin切换开销,因为我们将估计压缩到对Kotlin最有利的单点值。所以,在所有可能的结果中,我们上面描述的一分值是对Kotlin最有利的。总结在本文的开头,我们展示了一些主观判断,这些判断可能会误导开发人员比较编程语言。接下来,我们将讨论客观比较编程语言的困难,并执行一系列估算,以计算出使用Kotlin堆栈与Java堆栈完成软件项目所需的总工作量。在进行估算时,我们总是使用估算范围内对Kotlin最有利的值。从我们的分析来看,从Java切换到Kotlin似乎会导致完成软件项目所需的总工作量增加。更多的工作意味着切换到Kotlin的企业需要支付更多费用才能获得相同的功能,而用户必须等待更长的时间才能获得产品。一些开发人员可能会感到惊讶,并认为这个结果是不可接受的。在综合考虑各种场景后,Google最终决定支持KotlinAndroid开发。谷歌可能需要在这方面投入很多——谷歌云平台团队中没有人可以做类似的分析来弄清楚切换到一种新语言的负面影响吗?我认为Google员工是非常聪明的人,我相信他们在决定支持Kotlin之前进行了非常深入的分析。