作者 | Željko Trogrlić
翻译 | mycstar
本文分析了Kotlin和Java EE的关系,讨论了如何利用Kotlin的运算符,可空性和可选项来优化转换的效果。
将Java EE应用程序转换为Kotlin开始于框架的战斗,我们成功地超越了java老标准设置的所有障碍。在此过程中,新时代语言Kotlin特定的构造,使的代码更简洁而安全。
如果您没有阅读本系列的前两部分,可以在这里找到:
Kotlin和Java EE:第一部分 - 从Java到Kotlin(https://dzone.com/articles/kotlin-jee-part-one-from-java-to-kotlin)
Kotlin和Java EE:第二部分 - 插件的乐趣(https://dzone.com/articles/kotlin-and-java-ee-part-2-having-fun-with-plugins)
经过对前面两部分的回顾及修改,这里补充最后一些内容。
已有的转换
前两部分中的许多结构已经适用与Kotlin了。 下面我们来看看Set的定义:
由于Java不支持对象列表中的Set和其他集合的简单构造,我们必须使用Arrays类来创建List,然后将其转换为Set。Kotlin里就变成:
我们还将Java Bean转换为Kotlin数据类,使得它们简洁了很多。去掉所有的getter和setter,并自动得到了equals(),hashCode()和toString()。
这里要感谢编译器插件,可以伪造不变的对象,而不需要无参数的构造函数:
用lateinit关键字处理那些由框架初始化的值更容易一些,可以避免不必要的空值检查:
让我们看看还有什么可以改进的。
空值还是可选项?
这是一个非常棘手的问题。 Kotlin对可空值有很好的支持,当您使用第三方库时,这很有帮助。问题是当您有机会选择一个时,该使用什么?这是我们原来的Optional生产者和消费者对:
Kotlin解决方案将使用空值,所以变成:
空值可以出现在调用链的每个步骤中,因此您必须对所有调用使用问号。这解决了可空性问题,但它不漂亮。
然而,如果返回类型为Optional,结果为Optional.empty,则将略过该对象的所有未来单调调用,结果将为Optional.empty。对我来说,这看起来是一个更干净的解决方案,如果您打算从Java调用Kotlin代码,它也是一个更安全的解决方案。对于Java互操作,优先于空值。
运算符!
find, add , 和 delete是完全合法的方法名称,但是不是使用运算符更好呢?
Method | Operator |
---|
service.find(id) | service[id] |
service.add(kittenEntity) | service += kittenEntity |
我发现它不只是更短,而且更可读,因为代码不再是一大堆方法调用。小心只使用知名和易理解的操作符,否则,您将会遇到像Scala库一样大的混乱,然后您将需要一个操作符周期表。在数据存储库的情况下,类似MutableMap的接口工作得很好。请注意,我使用“plus assign”(+ =)运算符来持久化一个实体,因为原始集合包含它已经拥有的内容以及一个附加项。
以下是如何声明它们:
您可能希望保留原始方法,并对操作符进行包装,因为原始方法可以有返回值,而某些操作符则不能返回值。其他类似的选项是是“remove”和“contains”方法,因为它们可以用“minus
assign”( - =)和Kotlin的in运算符表示。其余的就留给你去探索。
结论
以惯用的方式写Kotlin代码的目的是要有更好的可读性和更安全的代码,我希望所提出的例子成功地实现了这一意图。该系列仅显示了几种方法来改进Java代码,同时使某些部分保持不变。值得探索的特点是:扩展函数,如果可能的话何时扩展,try/catch作为函数。探索一下,找出什么适合你的,玩得开心!
完整的代码可以在这里找到:https://github.com/zeljkot/fables-kotlin/tree/master/jee/idiomatic