2017 年,Google 宣布 Kotlin 成为 Android 的官方语言后,人们对于 Kotlin 的关注度就一直在上升。根据广大 Android 开发者反馈,Kotlin 帮助他们提高了生产效率和应用程序质量,对其有很高的满意度。并且数据显示 Google Play 商店中排名前 1000 的 Android 应用中有超过 80% 使用 Kotlin, Android 官方团队也都在用 Kotlin 写底层的源码。显然,对于 Android 开发者而言,Kotlin 已是一道无法绕过去的坎。
Kotlin vs Java:编程语言之战
在 Kotlin 出现之前,绝大部份 Android 开发者都是使用的 Java 语言,Java 有着许多明显的优点,如简单易学、面向对象、跨平台可移植性好等,在他们心中 Java 就是最好的编程语言。然而在 Kotlin 出现之后,这种对 Java 的信念有些动摇,程序员们开始搜索:
- Kotlin 和 Java 哪种语言更好?
- 对于 Android 开发,Kotlin 和 Java 哪个更好?
本文就将尝试回答以上的两个疑问。
什么是 Java?
Java 是一种广泛使用的计算机编程语言,拥有 跨平台、面向对象、泛型编程的特性,广泛应用于企业级 Web 应用开发和移动应用开发。
在 Android 系统中,系统 App 层和 Framework 层的几乎所有代码(目前已有部分改为 Kotlin)都由 Java 语言实现。
Java 语言的优点:
- 跨平台可移植性好:得益于 Java 虚拟机的存在,实现一次编写,到处运行(Write once, run anywhere)
- 简单易学:Java 是面向对象的编程语言,容易理解,省去多重加载、指针等难以理解的概念。并且实现了垃圾自动回收机制,大大简化了程序设计
- 健壮:Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证
- 安全可靠:它的许多库都由 Google、Apache 等受信任的公司管理
Java 语言的挑战:
- 运行速度较慢:Java 运行依赖于 Java 虚拟机,所以相对于其他语言(汇编、C/C++)编写的程序更慢,因为它不是直接执行机器码
- 缺少闭包(closure):闭包的缺失使得 Java 中函数式编程支持较差
- 测试驱动开发: 需要编写更多代码,并且会带来更高的编程错误风险
- 原生类型(Primitive types):原生类型的存在导致 Java 不是完美的面向对象语言,并且会造成一些编程问题。Java5 中通过自动装箱特性也没有完美解决
什么是 Kotlin
Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。
Kotlin 语言的优点:
- 语言简洁:Kotlin 具备简洁的语法和现代化的语法特性,与 Java 相比,用 Kotlin 编写的代码块更小。
- 与 Java 兼容性好:Kotlin 将代码编译为可以在 JVM 中执行的字节码。因此,所有用 Java 制作的库和框架都在 Kotlin 项目中都通用
- 安全性好:空安全机制降低了 NullPointerException 发生的概率
- 结构化并发:Kotlin 协程使异步代码与阻塞代码一样易于使用
Kotlin 语言的挑战:
- 不太受欢迎:与 Java 等其他成熟的语言相比,Kotlin 并不那么受欢迎。所以稳定的库、框架和教程更少
- 匹配弱模式:初始代码可读性变差
- 学习曲线陡峭:入门容易,精通困难
Kotlin 与 Java 比较
尽管 Kotlin 是官方支持的用于编写 Android 应用的语言,但您仍然可能觉得没有足够的理由进行切换。而以下对比,比较详细地囊括了 Kotlin 相比于 Java 的优点。
特征 | Java | Kotlin |
---|---|---|
检查异常 | ✅ | ❎ |
代码简洁 | 不是很简洁 | 比 Java 好 |
协程 | ❎ | ✅ |
数据类 | 需要编写大量样板代码 | 只需要在类定义中添加 data 关键字 |
扩展函数 | ❎ | ✅ |
高阶函数和 Lambda | 高阶函数是使用 Callables 实现的。Java 8 中引入了 Lambda 表达式 | 预建功能 |
内联函数 | ❎ | ✅ |
对委派的原生支持 | ❎ | ✅ |
非私有领域 | ✅ | ❎ |
空指针异常 | ✅ | ❎ |
基本数据类型 | 基本类型的变量不是对象 | 基本类型的变量是对象 |
智能转换 | ❎ | ✅ |
静态成员 | ✅ | ❎ |
三元运算符 | ✅ | ❎ |
通配符类型 | ✅ | ❎ |
使用语法对比
1. 空指针安全
NullPointerException 或 NPE 是 Java 的主要缺点之一,NPE 的唯一可能原因是显式调用抛出 NullPointerException。一些与初始化相关的数据不一致,或由外部 Java 代码引起的其他问题。 而 Kotlin 避免了 NullPointerException。每当可能抛出 NullPointerException 时,Kotlin 都会在编译时失败。
2. 数据类
使用 Java 编写数据类,通常开发者需要定义一个构造函数、几个存储数据的字段、每个字段的 getter 和 setter 函数,以及 equals()、hashCode() 和 toString() 函数。
class Book { private String title; private Author author; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Author getAuthor() { return author; } public void setAuthor(Author author) { this.author = author; } }
Kotlin 有一种非常简单的方法来创建这样的类。开发者只需要在类定义中包含 data 关键字,编译器将自行处理整个任务。
data class Book(var title: String, var author: Author)
3. 扩展函数
Kotlin 允许我们在不继承现有类的情况下扩展现有类的功能。意思是说,Kotlin 提供了开发具有新功能的类的能力,而无需从类继承,扩展函数可以做到这一点。 声明一个扩展函数,需要在它的名字前面加上一个接收器类型,即被扩展的类型。下面为 MutableList 添加了一个用于指定下标进行数值交换的函数:
fun MutableList <Int> .swap(index1: Int, index2: Int) { val tmp = this[index1] this[index1] = this[index2] this[index2] = tmp }
扩展函数中的“this”关键字对应于接收者对象,在“.”之前传递。现在可以在任何 MutableList 上调用这个函数:
val list = mutableListOf(1, 2, 3) list.swap(0, 2)
4. 智能转换
Kotlin 的编译器能够自动进行类型转换。在许多情况下,不需要在 Kotlin 中使用显式转换运算符,但 Kotlin 对不可变值有“is-checks”,并在需要时自动插入转换
fun demo(x: Any) { if (x is String) { print(x.length) // x 自动转换为字符串 } }
5. 类型推断
在 Kotlin 中,不必显式指定每个变量的类型。
fun main(args: Array < String > ) { val text = 10 //无需显示变量类型,Kotlin 自动识别为 Int 类型 println(text) }
6. 函数式编程
Kotlin 与 Java 对比中一个重要的区别在于 Kotlin 是一种函数式编程语言。Kotlin 由许多有用的方法组成,其中包括高阶函数、lambda 表达式、运算符重载、惰性求值等等。 函数式编程让 Kotlin 在集合方面更加方便:
fun main(args: Array < String > ) { val numbers = arrayListOf(15, -5, 11, -39) val nonNegativeNumbers = numbers.filter { it >= 0 } println(nonNegativeNumbers) }
高阶函数就是一个函数的参数是函数,或者返回值是函数,满足其中一个就是高阶函数。
考虑以下代码:
fun alphaNum(func: () -> Unit) {}
在上面的代码中,“func”是参数的名称,“() -> Unit”是函数类型。在这种情况下,func 是一个不接收任何参数且也不返回任何值的函数。
Lambda 表达式的本质其实是匿名函数,因为在其底层实现中还是通过匿名函数来实现的。Lambda 作为函数式编程的基础,其语法也是相当简单的。 一个 Lambda 表达式的例子:
val sum: (Int, Int) - > Int = { x, y - > x + y }
在上面的例子中,我们简单地声明了一个变量“sum”,它接受两个整数并将它们相加,然后以整数形式返回总和,然后我们只需使用“ sum(2, 2) ”来调用它。
总结
通过以上多方面对比可以看到,对于 Android 开发,Kotlin 显然更优于 Java。 之所以如此,是因为 Kotlin 与 Java 良好的互通性,从 Java 迁移到 Kotlin 的成本很低,并且 Kotlin 在 Java 基础上有了许多更优的改进。可以说 Kotlin 其实是站在了 Java 这个巨人的肩膀上,Kotlin 的出现,就是为了改良 Java 而生的。大胆预测,在不久的将来 Kotlin 会成为企业应用程序和移动设备的 First Language。
参考文献
Kotlin vs Java: Which is Better for Android App Development?