头图

未来的方向:由 Java 到 Kotlin 转变

zxdposter
English

前言

Kotlin 非常适合开发服务器端应用程序,可以让你编写简明且表现力强的代码, 同时保持与现有基于Java 的技术栈的完全兼容性以及平滑的学习曲线: 表现力:Kotlin 的革新式语言功能,例如支持类型安全的构建器和委托属性,有助于构建强大而易于使用的抽象。

这是摘录 kotlin 推广网站介绍这个语言的一段话,intelliJ 作为一家最懂程序员的公司,推出了 kotlin 语言,在使用了一段时间后,我认为 kotlin 完成有资格配得上这段评价。

  1. 非常适合开发服务器端
  2. 表现力强
  3. 兼容 java
  4. 强大易用

通过这段时间对 kotlin 的探索和了解,我想表达一下自己对 kotlin 对个人以及对企业的转变意义的思考。

转变的第一步:学好 java

如果是一个对 java 语言不太理解的新手,不太建议一开始就深入的了解 kotlin 的运作方式。

kotlin 语法本身是对 java 中很多写法的封装,将 java 繁琐的写法转变成风格简练的 kotlin 写法,再将 kotlin 最终转化为 java class。

举一个简单的例子:

val str = user?.id

上面一段简短的 kotlin 语句,转化为 java,就是:

String str = null
if (user != null) {
    str = user.id
}

最终 kotlin 还是要回归到 java 之上。

java 本身支撑着庞大的生态,绝大多数的企业、开源库,都依然还在使用 java 开发,kotlin 能够做到与 java 本身最大程度的兼容,非常不容易。

在可预见的未来里面,java 依然是开发界的基石,有着不可代替的地位,因此作为一个真正的 kotlin 语言学习者,java 仍然是必修课程。

转变的第二步:用心理解 kotlin

对一个刚刚接触 kotlin 的使用者来说,对各种符号、关键字的运用,绝对是一大阻力。

如果想能够快速的明白 kotlin 真正的长处,那么一定要理解 kotlin 为什么要这样干?

kotlin 为什么要使用问号 "?"

编写 java 的过程,最普遍,最困难的就是在处理空指针问题。

一个系统的输入,要考虑健壮性,必须要定义好哪些变量是可以为空的哪些变量又是不可为空的,当变量为空或者不为空,怎么去处理,上游代码给我的变量到底是不是空的

相信只要是一个考虑问题比较全面的程序员,在编写代码时都会有这样的担心。

kotlin 的目的就是要消灭程序员的担心。

第一个目的是直接在源头控制好变量为空或者不为空的情况,这样程序员在每一步的编写代码时,能够安心的知道,我这个变量是肯定不会为空的,如果是为空的情况,我已经有了应对办法。

第二个目的,是对可能为空的变量,能够有非常友好、简单、可读性强的处理

var userName = user?.name //当 user 不为空时将属性 name 复制给变量 userName

user?.let { // 当 user不为空时,打印 name 属性的值
    println(it.name)
}

user?.name?.let { // 当 user 以及 user.name 不为空时,打印 name 的值
    println(it)
} ?: println("name 为空") // 否则就输出 name 为空

user?.name = "kotlin" // 当 user 不为空时,给属性赋值

在这里可以稍作一下停顿,思考一下在 java 处理这样的逻辑,需要以怎样的方式实现。

这种写法足以打动任何在 java 中多次处理空指针问题、或者在代码运行一段时间莫名其妙出现空指针异常的程序员。

kotlin 吸收 stream

如果是一个对程序写法有些追求的程序员,相信一定不会错过 jdk1.8 语法中的 stream 和 lambda。

当我希望将 List<V> 中的 V 的某一个属性作为键转变为 Map<String, V> 时,stream 已经提供了非常简洁的写法:

Map<String, Choice> result = choices.stream().collect(Collectors.toMap(Choice::getName, Function.identity()));

java 已经非常简洁了,但是我每次希望做这样一种操作时,每次都在代码里面翻阅或者在网上搜索一遍用法。

在你使用了 kotlin 的做法后,相信你一定不会忘记它的写法:

val result = choices.map { it.name to it }.toMap()

对于复杂一些 stream 写法,你可能需要了解一番 java 如何向 kotlin 转变的,但是一般写法,只要求你删除 stream() 即可。

可以说,kotlin 完全吸收了 stream 的精髓,并且在这之上,青出于蓝而胜于蓝。

忘记 lombok 和 get set

lomok 是 java 世界中不可忽视的补充力量,他让简单的 get set 定义不再被程序员需要,但同时它对类的直接修改,也让很多深入使用的程序员诟病。

归根结底还是由于 java 中的封装概念,即控制有限字段暴露。

于是在 kotlin 中,不再有 get set 的概念,只有赋值和直接获取,只需要利用 privatevalvar 这个几个关键字,就能够实现控制字段的可见范围。

val name: String? = null // 能够获取,不能修改

var name: String? = null // 能够获取,能够修改

private val name: String? = null // 不可获取,不可修改

同样在 spring boot 中常用的 lombok 注解 @RequiredArgsConstructor,用简单的构造函数直接生成字段就能够代替。

本身 lombok 的注解对 kotlin 代码就不生效,当转变使用 kotlin 时,移除 lombok 也是理所应当的事情。

少就是多

当你能够理解 kotlin 这三点主要的用途,并能够应用自如,那么你将节省至少三分之一的代码量。

在代码的世界里,少就是多,减少冗余代码,就是在为自己争取开发时间,就是问题出现的概率在减少,就是问题发生时排查的速度在提高。

这或许就是 kotlin 为程序员积累的经过时间沉淀下来的实实在在的经验。

转变的第三步:实践

当你成功的被 kotlin 简洁干练的语法所吸引时,在经过团队中进步人士的同意下,希望替换为 kotlin 时,请注意到,kotlin 完全兼容 java,不仅是 kotlin 努力的方向,责任更在使用者身上。

替换本身是愉快的,之前的代码在你的手中一行一行的缩短,一个个空指针判断在被替换为简洁的问号,但是风险也在一步步的提高,每进行一步替换都要做好充分的回归测试,谁也无法预料在自动 java 到 kotlin 的代码转换器,能否将逻辑推理的那么严谨。

在替换的过程中

  1. 你可会遇到 java static 的方法无法与 kotlin 很好的兼容
  2. java 接口中的 default 方法,无法在 mybatis 中的 mapper 接口中应用
  3. 各种意想不到的困难

但是在这些困难背后,解决完后的意义远大于困难本身,因此这一些都是值得的。

现代语言中的 kotlin 和 swift3

kotlin 语法的诞生不是偶然因素,而且代码在不断发展过程中的必然结果。

对比 kotlin 与 swift3,你会发现两者惊人的相似,或许是由于两个语言中的设计人员有一些重合。

但是这些重合的点,何尝不是一代代的人使用后积累下来的产物,总是会有人去不断的追求更高效、更方便、更快捷的开发方式。

这些方式也一定会被现代的语言不断吸收,这些优点终将会被保留,一直延续到新一代的计算机出现。

对未来 kotlin 的展望

希望 kotlin 语言能够被更多人和更多的企业接受。

对个人来说接受的不一定是非要使用 kotlin 开发,更多需要接受的是 kotlin 在设计过程汇总烁烁发光的思想方式,不断要求自己在原本的 java 技能上获取精进。

对企业来说,减少错误成本、降低错误率、降低开发时间,永远是效率为上,理解 kotlin 带来的价值并能够合理的加以应用,是重中之重。

同时也希望未来 kotlin 本身能够再进一层,不再以 java 作为中间语言,而是能够直接一步到位,拥有完全属于自己的编写、编译、运行的体系。

阅读 712

Java 心得分享
分享 Java 使用心得
1.2k 声望
24 粉丝
0 条评论
1.2k 声望
24 粉丝
文章目录
宣传栏