从 Java 到 Kotlin:5 个令开发者感兴趣的特性
自 Google I/O 2017 之后,很明显 Kotlin 不再只是趋势,而是即将成为 Android 开发的标准。此外,Android Studio3.0 完全支持 Kotlin,无需再担心兼容性问题。对于从 Java 转的开发人员来说,很难不对它的几个特性感到兴奋。让我来介绍一下我自己最喜欢的👍
1. 命名参数
这算是每个 Java 开发者的恶梦:数量众多的参数在方法定义中的名字和顺序(例如在 Android 中创建 Cursor
或 SQLite
请求),如果没有文档或 IDE 的帮助,很难编写正确的 Java 代码:
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(this, CONTENT_URI, proj,
null, null, null);
}
幸运的是,Android Studio 团队添加了能高亮显示参数名字的特性。而 Kotlin 让它变得更容易,而无需 IDE 的帮助:
override fun onCreateLoader(i : Int, b : Bundle): Loader<Cursor>
= CursorLoader(sortOrder = null, selectionArgs = null, selection = null, context = this, uri = CONTENT_URI, projection = proj)
如上所示,我们可以随意安排参数列表的顺序。代码看起来更清晰,能够明确看到传递了哪些东西给方法,非常方便!
2. 数据类
这可能是对于曾经作为的 Java 程序员的 Kotlin 新手来说最有用和最“壮观”的特性。数据类使每个开发者生活更轻松,因为它只用一行代码就能描述 POJO 类。
最紧凑的 Java 写法:
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Kotlin ❤:
data class Person(val name: String, val age: Int)
来看看引擎盖下有些啥——编译器自动从主构造函数中声明的所有属性生成以下成员:
-
Any
类(相当于 Java 里的Object
)的标准方法:equals()
,hashCode()
,copy()
; -
Person
的toString()
(name=Michał, age=22); -
componentN()
函数; - 在 Kotlin 中没有真正的 getter 和 setter,取而代之的是对象属性。
这可以让我们不用再维护大量的样板代码,Kotlin 编译器都帮忙做了,让开发者更能聚焦程序的实际功能。
3. 空引用安全和安全调用
我称其为十亿美元的错误......那时,我正在设计第一个用于面向对象语言中引用的综合类型系统。 我的目标是确保所有引用的使用绝对安全,并由编译器自动执行检查。 但是我无法抗拒引入空引用的诱惑,仅仅因为它很容易实现。 这导致了无数的错误,漏洞和系统崩溃,这可能在过去四十年中造成了数十亿美元的损失。
--Tony Hoare, ALGOL W 语言发明者
Kotlin 的主要目标之一就是摆脱空引用异常。它仍然提供空引用,但仅用于与 Java 代码交互。默认的 Kotlin 类型是不可为空的,如果你尝试将它们设置为 null,则无法通过编译。
var bundle : Bundle = null // 编译不过
var bundle : Bundle? = null //nullable 类型, 可以编过
Java 中的一种典型情况:
public void sendMessage(@Nullable Person person, @NotNull Mailer mailer, String message) {
if (person == null || message == null) return;
PersonalInfo personalInfo = person.getPersonalInfo();
if (personalInfo == null) return;
String email = personalInfo.getEmail();
if (email == null) return;
mailer.sendMessage(email, message);
}
相同功能的 Kotlin 实现:
fun sendMessage(person: Person?, mailer: Mailer, message: String?) {
val email = person?.personalInfo?.email ?: return //Safe calls and Elvis operator
message?.let {
mailer.sendMessage(email, it)
}
}
简化判空检查让我们少写很多代码并且更聚焦,不仅让应用运行得更好,也让它看起来更好,是不是很棒?
4. 扩展属性
扩展属性在每次需要移除重复的类型转换时总能帮到我。
例如以传统方式编写的一段代码:
var myBigDecimal = 26 as BigDecimal
var otherBigDecimal : BigDecimal = myBigDecimal
为 Int
增加扩展属性 bd
:
val Int.bd : BigDecimal
get() = BigDecimal(this)
在我们扩展 Int
类之后,可以很容易地将 Int 值转换为 BigDecimals
,代码如下:
var myBigDecimal = 26.bd
var otherBigDecimal : BigDecimal = myBigDecimal
不用继承也无需任何设计模式(如装饰器模式)就能搞定。Kotlin 提供了快速简单的方式来为一个类扩展新的功能。
5. 智能类型转换
当涉及到类型转换时 Kotlin 表现地非常聪明 :) 来看一下这个简短的代码片段:
fun demo(x: Any) {
if (x is String) {
print(x.length) // x 自动转型为 String
}
}
关键词 is
相当于 Java 里的 instanceof
,但有其强大特性,编译器在 if
语句中检查对象的实例,并且在 if
代码块中将其视为 String
。在 When
代码块中也是如此:
when (x) {
is Int -> print(x + 1)
is String -> print(x.length + 1)
is IntArray -> print(x.sum())
}
这只是智能类型转换的简单介绍。还有“不安全”转换,“安全”(nullable)转换…… 阅读 Kotlin 文档可了解更多信息。
结语
作为一个新手,我对新语言感到兴奋。此外,JetBrains 的工具让我们可以更加容易地开始编码——自动将 Java 代码转为 Kotlin,与 Java 的完全可交互性,以及详细的文档等。Android 的未来对开发更友好,前途一片光明!
原文:Switching from Java to Kotlin: 5 exciting features for Android Developers
作者:Michał Smutkiewicz
编译:码王爷