设为首页 加入收藏

TOP

写给服务器端Java开发人员的Kotlin简介(二)
2018-11-20 22:09:48 】 浏览:376
Tags:写给 服务器 Java 开发 人员 Kotlin 简介
通常,这有助于避免拼写错误。


Kotlin类默认为final的。它提倡将继承作为一种有意识的设计选择。这在Spring AOP中是行不通的,但也不难弥补。我们需要将相关类标记为open —— Kotlin的非final关键字。


IntelliJ会给你一个友好的警告。


写给服务器端Java开发人员的Kotlin简介


你可以通过使用maven插件all open来解决这个问题。这个插件可以open带有特定注解的类。更简单的方法是将类标记为open


Kotlin严格执行null检查。它要求初始化所有标记为不可空的属性。它们可以在声明时或构造函数中初始化。这与依赖注入相反——依赖注入在运行时填充属性。


lateinit修饰符允许你指定属性将在使用之前被初始化。在下面的代码片段中,Kotlin相信config对象将在首次使用之前被初始化。


虽然lateinit对于自动装配很有用,但我建议谨慎地使用它。另一方面,它会关闭属性上的编译时空检查。如果在第一次使用时是null仍然会出现运行时错误,但是会丢失很多编译时空检查。


构造函数注入可以作为一种替代方法。这与Spring DI可以很好地配合,并消除了许多混乱。例如:


这是Kotlin引导你遵循最佳实践的一个很好的例子。


Hibernate和Kotlin可以很好地搭配使用,不需要做大的修改。一个典型的实体类如下所示:


在上面的代码片段中,我们利用了几个Kotlin特性:


属性


通过使用属性语法,我们就不必显式地定义gettersetter了。这减少了混乱,使我们能够专注于数据模型。


类型推断


在我们可以提供初始值的情况下,我们可以跳过类型规范,因为它可以被推断出来。例如:


modelNumber属性会被推断为String类型。


表达式


如果我们稍微仔细地看下toString()方法,就会发现它有与Java有一些不同:


它没有返回语句。这里,我们使用了Kotlin表达式。对于返回单个表达式的函数,我们可以省略花括号,通过等号赋值。


字符串模板


在这里,我们可以更自然地使用模板。Kotlin允许在任何字符串中嵌入${表达式}。这消除了笨拙的连接或对String.format等外部辅助程序的依赖。


相等测试


equals方法中,你可能已经注意到了这个表达式:


它用==符号比较两个字符串。在Java中,这是一个长期存在的问题,它将字符串视为相等测试的特殊情况。Kotlin最终修复了这个问题,始终把==用于结构相等测试(Java中的equals())。把===用于引用相等检查。


数据类


Kotlin还提供一种特殊类型的类,称为数据类。当类的主要目的是保存数据时,这些类就特别适合。数据类会自动生成equals()hashCode()toString()方法,进一步减少了样板文件。


有了数据类,我们的最后一个示例就可以改成:


这两个属性都作为构造函数的参数传入。equalshashCodetoString是由数据类提供的。


但是,数据类不提供默认构造函数。这是对于Hibernate而言是个问题,它使用默认构造函数来创建实体对象。这里,我们可以利用kotlin-jpa插件,它为JPA实体类生成额外的零参数构造函数。


在JVM语言领域,Kotlin的与众不同之处在于,它不仅关注工程的优雅性,而且解决了现实世界中的问题。


解决Java中的NPE是Kotlin的主要目标之一。将Kotlin引入项目时,显式空检查是最明显的变化。


Kotlin通过引入一些新的操作符解决了空值安全问题。Kotlin的?操作符就提供了空安全调用,例如:


只有当car对象不为空时,才会读取model属性。如果car为空,model计算为空。注意model的类型是Model?——表示结果可以为空。此时,流分析就开始起作用了,我们可以在任何使用model 变量的代码中进行NPE编译时检查。


这也可以用于链式调用:


下面是等价的Java代码:


一个大型的代码库会省掉许多这样的null检查。编译时安全自动地完成这些检查可以节省大量的开发时间。


在表达式求值为空的情况下,可以使用Elvis操作符( ?: )提供默认值:


val year = car?.model?.year ?: 1990


在上面的代码片段中,如果year最终为null,则使用值1990。如果左边的表达式为空,则?: 操作符取右边的值。


Kotlin以Java 8的功能为基础构建,并提供了一等函数。一等函数可以存储在变量/数据结构中并传递出去。例如,在Java中,我们可以返回函数:


Kotlin让这个过程变得更加自然,让我们可以清晰地表达意图:


我们很容易调用fn1及结果函数:


输出
25.0


虽然以上功能在Java中也可以实现,但并不直接,并且包含样板代码。


提供这些功能是为了鼓励团队尝试FP概念,开发出更符合要求的代码,从而得到更稳定的产品。


注意,Kotlin和Java的lambda语法略有不同。这在早期可能会给开发人员带来烦恼。


Java代码:


等价的Kotlin代码:


随着时间的推移,情况就变得明显了,Kotlin支持的应用场景需要修改后的语法。


Kotlin最被低估的优点之一是它可以减少项目中的文件数量。Kotlin文件可以包含多个/混合类声明、函数和枚举类等其他结构。这提供了许多Java没有提供的可能性。另一方面,它提供了一种新的选择——组织类和函数的正确方法是什么?


在《代码整洁之道》一书中,Robert C Martin打了报纸的比方。好代码应该读起来和报纸一样——高级结构在文件上部,越往下面越详细。这个文件应该讲述一个紧凑的故事。Kotlin的代码布局从这个比喻中可见一斑。


建议是——把相似的东西放在一起——放在更大的上下文里。


虽然Kotlin不会阻止你放弃“结构(structure)”,但这样做会使后续的代码导航变得困难。组织东西要以它们之间的关系和使用顺序为依据,例如:


在实践中,通过减少为获得全貌而需要跳转的文件数量,可以显著减少脑力开销。


一个常见的例子是Spring JPA库,它使包变得混乱。可以把它们重新组织到同一个文件中:


上述内容的最终结果是代码行数(LOC)显著减少。这直接影响了交付速度和可维护性。


我们统计了Java项目中移植到Kotlin的文件数量和代码行数。这是一个典型的REST服务,包含数据模型、一些逻辑和缓存。在Kotlin版本中,LOC减少了大约50%。开发人员在跨文件浏览和编写样板代码上消耗的时间明显减少。


编写简洁的代码是一个宽泛的话题,这取决于语言、设计和技术的结合。然而,Kotlin提供了一个良好的工具集,为团队的成功奠定了基础。下面是一些例子。


类型推断最终会减少代码中的噪音。这有助于开发人员关注代码的目标。


类型推断可能会增加我们跟踪正在处理的对象的难度,这是一种常见的担忧。从实际经验来看,这种担忧只在少数情况下有必要,通常少于5%。在大多数情况下,类型是显而易见的。


下面的例子:


变成了:


在Kotlin中,也可以指定类型:


值得注意的是,Kotlin提供了一个全面的解决方案。例如,在Kotlin中,我们可以将函数类型定义为:


另一方面,Java 10通过检查右边表达式的类型推断类型。这引入了一些限制。如果我们尝试在Java中执行上述操作,我们会得到一个错误:


写给服务器端Java开发人员的Kotlin简介


这是Kotlin中一个方便的特性,它允许我们为现有类型分配

首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇同时使用scanf()函数和getchar().. 下一篇Java并发-从同步容器到并发容器

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目