今天是新年上班的第一个周末,很多春节的想法想用文字表达出来,却总是感觉词穷墨尽,无法用语言准备地表达我的想法。我想,大约是迷失了太久,连温情的文字都抛弃了我。新的一年,我会用100%的热情去爱你,希望你不要离我远去...
鉴于这样的一种状态,我想依然用一篇技术文章,开始新年的第一篇。好了,Let's get started。
学习Kotlin语言的大部分程序员都是从Java阵营转过来的。因此,从Java思想转换到Kotlin是学习Kotlin语言至关重要的一步。这篇文章将介绍从Java语言转换到Kotlin语言几个不一样的地方,让你在Kotlin语言开发中,更加轻车熟路!
Static (静态变量,方法)
这大约是从Java语言转换到Kotlin语言遇到的第一个难题,Kotlin语言中没有Static关键字,要实现类似Java静态变量或者静态方法的需求常常让人不知所措。其实,虽然Kotlin语言中没有static关键字,却提供另外一个解决方案Companion Object(伴随对象) ,伴随对象可以很好地解决Kotlin语言没有static关键字的问题,并且在转换到Java语言时,会自动转换为static关键字。看下面的例子:
Java
class A {
private static A instance;
private A() {}
public static A getInstance() {
if(null == instance) instance = new A();
return instance;
}
}
这段代码和下面的Kotlin代码是等价的:
Kotlin
class A {
companion object {
private var instance: A? = null
private constructor() {}
public fun getInstance(): A {
if(null == instance) instance = A()
return instance!!
}
}
}
使用上面的方式声明后,我们就可以使用静态调用的方式来使用getInstance()方法了:
// Java语言调用
A a = A.getInstance();
// Kotlin语言调用
val a = A.getInstance()
这个知识点非常关键,在日常开发中经常用到,一定要铭记在心。
克服了第一个不同点之后,我们来看第二个不同点:
Null safe
Kotlin语言是一门空值安全的语言,它使用了类似Swift的可选值解决方案,具体语法我已经在文章 Optional Value (可选值) 进行过讲解,如果对该知识点比较陌生,可以参看这篇文章。由于这个概念在Java语言中从来不曾出现过,因此对于Kotlin新手来说,这依然是一个非常棘手的问题。我相信,你们一定有过这样的疑问:
- 什么时候应该使用?操作符
- 使用时候应该使用!!操作符
- 通篇的?好难看,可否减少?操作符的使用
是的,我也有过同样的疑问,下面我来给大家一一解答:
什么时候应该使用?操作符
这个问题,其实并不难,答案就是:在你无法确定当前值是否为空,而你又不需要出现空指针异常的时候,就可以使用?操作符进行调用。
什么时候应该使用!!操作符
这个问题,其实在之前的文章中也有提到过,答案也很简单:如果你非常依赖当前数据,一旦数据为空,你希望程序出现空指针异常,或者你希望程序主动上报这个错误,就可以使用!!操作符,这会明确导致空指针异常。但却保证了逻辑的健壮性,在某些情况下的确是需要的。
通篇的?好难看,可否减少?操作符的使用
这的确是一个问题,例如,在Android开发中,我们常常在成员变量中声明需要使用的组件,这个时候的第一个想法就是使用可选值声明。看起来是合情合理的,其实却有点奇怪。因为组件一旦声明,就表示我们一定会用到这个组件,并且这个组件在用的时候一定不会为空。使用?操作符的后遗症就是,后面调用必须带上?或者!!,实在是Very ugly。不过,不用担心,聪明的Kotlin提供了一个非常漂亮的解决方案Delegation,这里只需要使用代理里面的代理属性就可以解决这个问题。使用方法大致如下:
val mTextView by bindView(R.id.text_view)
使用了代理属性之后,变量只有在第一次调用的时候才会被赋值,既保证了Null safe ,又保证了无需使用?操作符。因此,在遇到太多?调用的时候,可以思考是否需要使用Delegation来解决这个问题,有关代理的介绍请参考我的另外一个文章 Delegation。
如果你没有使用过Java8,在Kotlin语言开发中Lambda表达式恐怕会是你开发中遇到的一道坎,其实Lambda表达式并不能,你把它当成匿名函数来看就好了,Lambda表达式只是去掉了函数声明的函数而已。基本语法要切记,看下面的简单例子:
{x , y -> x + y}
关于Lambda表达式,了解更多,请参看我的文章Lambda and Extension。
Lambda表达式虽然是新语言的一个特性,但至少在Java8语言中出现过,对于从Java8阵营转换过来的同学, 或许不会太陌生。而接下来这个知识点在Java阵营中从来未曾出现过,很多同学恐怕要懵逼了...
Extension
这个特性第一次知道,是我在学习OC语言的时候,他和OC语言中的概念Category是相同的。因此,如果你是从OC阵营转换过来的话,这对你来说应该也不陌生。这个特性是我最喜欢的特性之一,但对于Kotlin新手来说应该算是最难掌握的特性之一了,尤其是在配合Lambda表达式一起使用的时候,常常会让新手同学云里雾里,摸不清头脑。这个知识点的基本语法很简单,这里就不赘述了,想要彻底弄懂这个特性,请参看我的另一篇文章Lambda and Extension。
反射语法
这也是Kotlin新手经常迷惑的一个问题,Kotlin语言针对反射有自己的解决方案,所有反射的对应类名前面均添加了K以和Java语言区分开来。
在Android开发中,我们经常要通过Intent启动Activity,看一下Java语言中的写法:
Intent intent = new Intent(this , MainActivity.class);
startActivity(intent);
这在Kotlin语言中,必须这样写:
val intent = Intent(this , MainActivity::class.java)
startActivity(intent)
原因很简单,::class返回的是KClass对象,只有调用.java才能转换成Java语言的Class对象。这个地方在Android开发中经常用到,这里的使用方法可以先记住,后面慢慢理解Kotlin语言的反射和Java的反射有什么不同。
== 或 ===
在Java语言中,判断两个对象是否完全相等(即是否在同一个地址上)使用==,判断两个对象的值是否相等使用equals方法进行处理,如果你要实现自己的相等逻辑则需要重写equals方法。而在Kotlin语言中,Kotlin编译器并不推荐我们使用equals方法,你应该经常会看到编译器在你使用equals方法的地方置灰,提示你写法并不推荐。
这里其实也是一个非常容易让人混淆的地方,Kotlin语言中的==就等同于Java语言中的equals,而===才是判断两个对象地址是否相等的正确操作符。这里一定要切记。
操作符重载
一定有人会奇怪,为什么==的意义和Java语言中的不一样了,道理其实很简单,Kotlin语言支持操作符重载。通过操作符重载可以对某个操作符赋予不一样的意义,简化代码逻辑。这里后续我会专门写一篇文章来讲解这个知识点,关于这个知识点的具体介绍请先参看官方文档。
不过,操作符重载在日常开发中并不常遇到,只是碰到类似的问题一定要明白为什么会这样。
object
这和Java的基类Object完全不是一回事,这里的object是声明一个实实在在的堆对象的意思,在什么地方会使用到呢?其实依然非常常见!
在日常Android开发中,我们常常会遇到一些事件监听器,如果事件监听器只有一个方法,Kotlin编译器会提示你转换为Lambda表达式,而如果监听器有多个编译器,就无法转换成Lambda表达式了。这个时候问题来了,怎么创建匿名内部类呢?糟糕了,Kotlin语言并不支持直接创建匿名内部类!!!
怎么办呢?聪明的Kotlin早就想到了这一点,使用object语法即可解决这个问题:
val textWatcher = object: android.text.TextWatcher {
override fun afterTextChanged(s: Editable?) {
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
mBindButton.isEnabled = !emptyCheck()
}
}
关于Kotlin语言的语法还很多,这篇文章仅仅介绍一些对于Kotlin新手比较棘手的几个问题,建议新同学收藏这篇文章,在遇到不知所措的问题的时候,来即时查阅,如果找不到你想要查阅的内容,请在评论下方告诉我!
欢迎加入Kotlin交流群
如果你也喜欢Kotlin语言,欢迎加入我的Kotlin交流群: 329673958 ,一起来参与Kotlin语言的推广工作。
最后,祝大家新年快乐,心想事成!有钱的捧个钱场,没钱的捧个人场!谢谢大家!