« 主页

实战 Kotlin in Android

版权声明:眯眼探云原创,可随意转载,请保留该版权声明及链接:https://tyun.fun/post/13.java-to-kotlin/

最近我们在把线上的安卓项目的开发语言从 Java 切换到了 Kotlin。其中自然有许多故事可讲,首先要讲的就是,为什么要使用新语言,为什么选择了 Kotlin。

如果有时间,下次再来讲实践 Kotlin 的感受如何(很爽!!),常见的坑有哪些。

摘要

本文答了这么几个问题:

一、为什么要学习和使用新的语言? 二、好几种运行于 jvm 上的语言,为什么选择了 Kotlin? 三、从 Java 到 Kotlin,我们经历了哪几个阶段?

Java 太啰嗦,而且发展太慢

存在即是合理,虽然我接下来要吐槽 Java 不够好,但是,不妨碍学习和使用 Java 的人依然非常多,不妨碍 Java 继续蓬勃发展。Java 的狂热粉丝们可以直接跳过。

在吐槽前,我还是先说一下我的语言学习/使用经历,稍稍证明一下,我还是算的上经验丰富。

  • 我最早是写 C#(3年),当时写网站,对网页相关技术也非常熟(相对于现在来说,早就落伍了)。
  • 后来转了 Java 做安卓研发(2010年),见识了团队中的高手(20年以上编程经验)写代码,从此对优秀的代码有了不一样的认识,直到现在都还在不断的提升自己。
  • 除了做安卓研发,还用 Python + Django 框架为公司内部写了一个小网站。
  • 还有一年时间由于公司人手不足,转做 iOS,用了近一年的 Objective-C。
  • 后来,为了研究 ReactNative,又花时间深入学习了 Javascript(以前做网页开发的时候就有一些 Javascript 经验)。可惜 ReactNative 并没有在项目实践中用上。

其他一些学过但用的少的语言就不讲了。

接下来就开始吐槽 Java。

缺乏优秀的类的属性设计

通俗易懂点,就是 getter/setter 的处理。看如下的代码:

 public class Person {
   private String name;
   public getName() { return name; }
   public setName(String name) { this.name = name; }
 }

你无法想象 Java 代码中有多少这样毫无意义的 getter/setter 代码。但你还是得要它们。

就连 Objective-C 这种公认语法怪异的语言,对属性的设计都比 Java 好很多。

而且这并不是什么难以解决的问题,在编译器里面加一点小戏法就搞定了:

  • 当声明一个属性的时候,编译器在编译的时候自动生成相应的 getter/setter 方法。而你只有在需要的时候,才去定义自己的 getter/setter。

迟来的 lambda

C# 在09年左右加入的 LINQ,超级方便的集合操作有木有!

09年,09年!

然后看看前两年 Java8 才出个 lambda,然后增强了集合相关的功能。

而且更令人不爽的是,现在安卓开发都还用不上 Java8。如果要想在安卓开发中用上 Java8(的一个子集),你要完全放弃低版本的安卓用户,或者使用第三方库。

Java 的发展实在太慢

总的来说,Java 的发展实在是太慢了。其中原因非常的多,比如历史包袱大,比如 Oracle……但最终的事实就是:发展实在太慢了。

但 Java 现在还活着,而且还活的很好,自然有它的优势。一是用 Java 的人多,生态圈好。

二是……

屌屌的 JVM

但是,但是,不得不说,Java 最屌的早就不是 Java 语言本身了,而是 JVM。

虽然我依然想吐槽 JVM 吃内存厉害的不像话。但是,它真的很屌。广大程序员早已经用实际行动证明了这一点。

围绕 JVM 已经发展出了不少的新语言,最优秀,最广为人知的有:Scala,Groovy,Closure,Kotlin

这些语言都可以编译成 Java 的中间字节码,运行于 JVM 上面。

而且这些语言都有非常高的流行度。其中 Kotlin 是流行度最低的。那为什么偏偏选中了 Kotlin?

Jvm languages trends

Scala 的设计核心是函数式编程,而且据说实践的情况是,有些从 Java 切换到了 Scala 之后,一年之后,并没有实际效率的提升。原因是:这个语言太复杂了,不太好掌握。我记得有次和一位前辈(@润)聊过,提到 Scala 中下划线的用法非常之多。多到什么程度呢?网上有很多专门关于 Scala 下划线的疑问,以及很多专门总结下划线使用的博客。

Groovy 的设计主要是想成为一个脚本语言。而且还有一个 Groovy on Rails 的项目,现在怎么样了我也没去关注。不过作为脚本语言,Groovy 还是成功的。现在 Java 平台最流行的编译工具 Gradle 的编译脚本,主要就是用 Groovy 在写。

Closure 也是函数式编程语言,而它的主要想法是重现 Lisp 的荣光。千万不要小看 Lisp 这门语言。黑客与画家的作者可是极力推荐这门语言。但是 Lisp 一直没有成为主流语言,还是有些自身的原因。根据我的使用体验来看,这货的思维方式抽象程度相对较高,而且语法相对于 C 来说比较怪异。毕竟现在主流的教育都是类 C 的语言,导致其他类型的语言风格并不容易流行。

Kotlin,根据官方的描述来看,其目标就是想成为一个 Better Java。和前面几门语言的目标不一样哦!来看看官方的描述:

Statically typed programming language for the JVM, Android and the browser

这,不就是 Java 的主要领域吗?而且,现在那些优秀的语言特性,以及函数式编程,都有哦~

也就是说,从官方定位来看,如果要选一门语言来代替 Java 作为日常工作的语言,Kotlin 就是最合适的了

当然,不能看官方的定位,还得看实力。

足够成熟

前两年我就开始关注 Kotlin 了,而自从今年二月份官方正式发布了 1.0 以来,我就提高了关注度。在程序员的世界中,1.0通常代表着:足够成熟。

而根据实际的情况来看:

  1. 配套工具足够成熟。毕竟 JetBrains 的核心竞争力就是做 IDE。
  2. Kotlin 可以和 Java 100% 交互,也就是说,Java 的生态系统,就是 Kotlin 的生态系统。足够成熟。
  3. 从语言本身来讲,1.0,至少代表着 JetBrains 已经认为它足够成熟。所以,可以认为语言本身也足够成熟。

成熟是一回事,它是不是足够好呢?

来自 JetBrains

恩…… JetBrains,脑浆喷射?

JetBrains 家的 IDE 现在是公认的最好用的 Java IDE。AndroidStudio就是基于 IntelliJ Idea 做的。而且 Google 现在已经公开放弃了对 Eclipse 的支持。

除了 IntelliJ,JetBrains 家的其他 IDE 也是做的非常的优秀:PyCharm,PhpStorm,Intellij Idea,WebStorm,RubyMine……

你用的哪一个?

能够做出如此出色的 IDE,在开发实践上有如此丰富的经验,那么有理由相信,他们推出的 Kotlin 非常值得一试。

完美的工具支持

JetBrains 家是做啥的?做工具的啊!

所以 Kotlin 的工具支持真的是非常的完美。

IntelliJ Idea/Android Studio 中直接用上,非常方便。

静态代码分析。快速 IDE 纠错替换。

还有 Java 代码转换工具。

工具是保证开发效率的非常关键的一环,有 JetBrains 背书,这方面,我必须给10分。

风险低

在项目中替换技术栈,是一件非常有风险的事情。所以风险是一项非常重要的考虑因素。

而 Kotlin 设计之初,最关键的一点就是和 Java 100% 交互,也就是说,项目中完全可以混合这两种语言的使用。那真是太方便了:可以逐步将项目中的 Java 替换为 Kotlin。妈妈再也不担心使用 Kotlin 出问题了。

Kotlin 语言本身有哪些优点呢?

Google 也会做出一些烂东西,所以并不是大公司出品就一定很好。所以,还是必须得检验一下 Kotlin 本身。

对安卓非常友好

要将 kotlin 代码引入到项目中是非常方便的。官方的插件可以直接帮你进行相关的配置。

而且 Kotlin Android Plugin 可以让你逃离 findViewById 的苦海。比 ButterKnife 还要省心。ButterKnife 你还要挨个去声明 InjectView。

Kotlin 的核心库非常小,官方介绍,大约5000多个方法。直接当成一个依赖打包到安卓项目中丝毫没有压力。

代码简洁

有这么一个观点:你的代码写的越少,出错的可能性越小。

不知道别人怎么看,反正我是信了。

Koltin 简洁的代码风格我非常喜欢。就拿开篇的那个例子来说。Kotlin 里面的定义可以是:

 class Person(val name: String)

That’s all。

而且,Kotlin 还专门有针对数据类进行优化:data class。让你非常高效的定义数据类,而数据类该有的 copy,equals,toString 等等应有尽有。方便的不要不要的。

强大的集合操作

函数式编程是最近两年非常非常热的方向,Kotlin 当然也少不了函数式编程。

函数式编程非常值得一讲,但在本文中不算是重点。希望以后有机会能写点相关的。

函数式编程和 lambda 的结合,集合中的元素随你揉捏。

来对比看一下这两段代码(Java):

 for (String str in list) {
   if(str.equals("Hello World")){
     return str;
   }
 }

(Kotlin):

list.any { it == "Hello World" }

看出差别没有?表达出相同的意图,明显 Kotlin 做的更好,而且更简洁。

虽然现在 Java8 也增强了这一部分,不过,安卓开发还用不上,那就等于没有。

优雅的 Null Safety

写 Java,最常修的 BUG 应该就是 NullPointerException 了。Java8 也提供了一个解决方案:丑陋的 Optional。请允许我用丑陋来描述它。因为它只是利用了现有的语言特性进行了一层封装。而 Kotlin 提供的是真正的语言级的 Null Safety 的支持。

你希望在代码中看到满篇的参数都是 Optional 封装的吗?还有满篇的 isPresent,ifPresent 之类的方法调用?

Kotlin 相应的代码看起来就简洁多了。

可为空,加个"?“就行了val str: String? = null 强制转化为非空进行使用:str!!.length 如果不为空则调用:str?.length

类的扩展

如果你是个纯的 Java 程序员,没有接触过这个概念。那么听了它以后,你会高兴的跳起来。

Java 里面常见的一个蛋疼点就是,写一堆的各种 Utils: StringUtils, DateUtils……

用起来也不优雅,比如:StringUtils.xxx(str, xxx)

类的扩展来了,这种 Utils 方法的使用方式完全就被革新了。

有这么神奇吗?有!

类的扩展其实就是给已经存在的类增加方法,而不用去继承它。你可以认为它是一个语法糖,不过这个语法糖真的好甜!

做个比较,比如我们需要一个方法来处理 String,给它加上一段"hello world”,请比较下面两种调用方式

Java: StringUtils.addHelloWorld(str) Kotlin: str.addHelloWorld()

怎么样,看起来舒服多了吧。

而且这只是最基本的功效,与函数式编程结合起来以后,还有些更 NB 的用法,不过那需要一些更深入的知识,这里就不展示了。

还有很多很多……

Kotlin 除开上面的几个大的特点,还有其他非常多优秀的语言特性。这里肯定是讲不完的。

当然,没有什么东西是完美的,我也并不期望 Kotlin 是完美的,但目前为止,相对于 Java 来说,Kotlin 提供的许多优秀的语言特性,用起来,切实的提高了我的编程效率。

问题

在项目中使用 Kotlin 替换 Java,最大的问题,应该就是学习成本了,尤其是,整个组的学习成本。

但毕竟是和 Java 一脉相承的语言,Kotlin 学习起来其实非常容易。所以,总体来看,收益是远远大于成本的

实战过程

毕竟是在生产环境中使用一门新语言,所以在整过过程中,我们是非常谨慎的。

预热:调研

首先,肯定还是调研,看 Kotlin 语言怎么样,配套的东西怎么样。总之就是:可以用不?

经过调研的阶段,我们确定了:我们可以整个组来学习,并在项目中将 Java 替换为 Kotlin。

阶段一:学习

在项目中实际尝试 Kotlin 的前两个月,我们就开始组织学习 Kotlin。

学习的方式主要是先看理论知识,然后做一下官方的练习题。在这过程中,不断的聚在一起交流学习心得。

阶段二:尝试

在进行全项目转化以前,我们先开始尝试局部转化。

Kotlin 提供的转化工具非常好用,转化了过后,虽然少部分代码依然需要人工的处理,但整体上来讲,效率已经非常高。

经过了这一步,我们几乎可以确信,将项目整体转化为 Kotlin 完全没有问题。

阶段三:大规模转化

整个项目的转化花的时间比预计的稍微多一些,不过依然在掌控之中。

在过程中也遇到了不少的问题,而解决这些问题,也就让我们对 Kotlin 更加的熟练。是一个非常好的学习机会。

阶段四:The Future

虽然整体的转化非常的顺利,但是可以预见,还是会有一些潜在的问题。所以,要做的还是对 APP 进行一些回归测试,先保证功能的稳定运行,然后在后续的时间内,继续 BUG 的修复。

我相信,在将来,Kotlin 一定可以带来极大的开发效率提升以及稳定性的提升。

总结和思考

对新的编程语言的学习,其实最重要的并不止是语言本身,更重要的是,学习新的思想。

Kotlin 吸收了非常多的现代语言的优秀特性,换句话说,就是吸收了非常多的优秀的思想。

而每当用好了一项新特性,其实就是掌握了一个新的思想。对于程序的设计是非常有帮助的。

而且,非常期待 Kotlin 带来的效率提升,以及使用 Kotlin 带来的编程的愉悦感觉!

Enjoy!