快速上手Kotlin

今天是新年上班的第一個周末,很多春節(jié)的想法想用文字表達(dá)出來,卻總是感覺詞窮墨盡,無法用語言準(zhǔn)備地表達(dá)我的想法。我想,大約是迷失了太久,連溫情的文字都拋棄了我。新的一年,我會用100%的熱情去愛你,希望你不要離我遠(yuǎn)去...

鑒于這樣的一種狀態(tài),我想依然用一篇技術(shù)文章,開始新年的第一篇簡書。好了,Let's get started。

學(xué)習(xí)Kotlin語言的大部分程序員都是從Java陣營轉(zhuǎn)過來的。因此,從Java思想轉(zhuǎn)換到Kotlin是學(xué)習(xí)Kotlin語言至關(guān)重要的一步。這篇文章將介紹從Java語言轉(zhuǎn)換到Kotlin語言幾個不一樣的地方,讓你在Kotlin語言開發(fā)中,更加輕車熟路!

Static (靜態(tài)變量,方法)

這大約是從Java語言轉(zhuǎn)換到Kotlin語言遇到的第一個難題,Kotlin語言中沒有Static關(guān)鍵字,要實現(xiàn)類似Java靜態(tài)變量或者靜態(tài)方法的需求常常讓人不知所措。其實,雖然Kotlin語言中沒有static關(guān)鍵字,卻提供另外一個解決方案Companion Object(伴隨對象) ,伴隨對象可以很好地解決Kotlin語言沒有static關(guān)鍵字的問題,并且在轉(zhuǎn)換到Java語言時,會自動轉(zhuǎn)換為static關(guān)鍵字。看下面的例子:

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!!
         }
    }
}

使用上面的方式聲明后,我們就可以使用靜態(tài)調(diào)用的方式來使用getInstance()方法了:

// Java語言調(diào)用
A a = A.getInstance();
// Kotlin語言調(diào)用
val a = A.getInstance()

這個知識點非常關(guān)鍵,在日常開發(fā)中經(jīng)常用到,一定要銘記在心。

克服了第一個不同點之后,我們來看第二個不同點:

Null safe

Kotlin語言是一門空值安全的語言,它使用了類似Swift的可選值解決方案,具體語法我已經(jīng)在文章 Optional Value (可選值) 進(jìn)行過講解,如果對該知識點比較陌生,可以參看這篇文章。由于這個概念在Java語言中從來不曾出現(xiàn)過,因此對于Kotlin新手來說,這依然是一個非常棘手的問題。我相信,你們一定有過這樣的疑問:

  • 什么時候應(yīng)該使用?操作符
  • 使用時候應(yīng)該使用!!操作符
  • 通篇的?好難看,可否減少?操作符的使用

是的,我也有過同樣的疑問,下面我來給大家一一解答:

什么時候應(yīng)該使用?操作符

這個問題,其實并不難,答案就是:在你無法確定當(dāng)前值是否為空,而你又不需要出現(xiàn)空指針異常的時候,就可以使用?操作符進(jìn)行調(diào)用。

什么時候應(yīng)該使用??!操作符

這個問題,其實在之前的文章中也有提到過,答案也很簡單:如果你非常依賴當(dāng)前數(shù)據(jù),一旦數(shù)據(jù)為空,你希望程序出現(xiàn)空指針異常,或者你希望程序主動上報這個錯誤,就可以使用!!操作符,這會明確導(dǎo)致空指針異常。但卻保證了邏輯的健壯性,在某些情況下的確是需要的。

通篇的?好難看,可否減少?操作符的使用

這的確是一個問題,例如,在Android開發(fā)中,我們常常在成員變量中聲明需要使用的組件,這個時候的第一個想法就是使用可選值聲明??雌饋硎呛锨楹侠淼?,其實卻有點奇怪。因為組件一旦聲明,就表示我們一定會用到這個組件,并且這個組件在用的時候一定不會為空。使用?操作符的后遺癥就是,后面調(diào)用必須帶上?或者??!,實在是Very ugly。不過,不用擔(dān)心,聰明的Kotlin提供了一個非常漂亮的解決方案Delegation,這里只需要使用代理里面的代理屬性就可以解決這個問題。使用方法大致如下:

val mTextView by bindView(R.id.text_view)

使用了代理屬性之后,變量只有在第一次調(diào)用的時候才會被賦值,既保證了Null safe ,又保證了無需使用?操作符。因此,在遇到太多?調(diào)用的時候,可以思考是否需要使用Delegation來解決這個問題,有關(guān)代理的介紹請參考我的另外一個文章 Delegation

如果你沒有使用過Java8,在Kotlin語言開發(fā)中Lambda表達(dá)式恐怕會是你開發(fā)中遇到的一道坎,其實Lambda表達(dá)式并不能,你把它當(dāng)成匿名函數(shù)來看就好了,Lambda表達(dá)式只是去掉了函數(shù)聲明的函數(shù)而已。基本語法要切記,看下面的簡單例子:

{x , y -> x + y}

關(guān)于Lambda表達(dá)式,了解更多,請參看我的文章Lambda and Extension。

Lambda表達(dá)式雖然是新語言的一個特性,但至少在Java8語言中出現(xiàn)過,對于從Java8陣營轉(zhuǎn)換過來的同學(xué), 或許不會太陌生。而接下來這個知識點在Java陣營中從來未曾出現(xiàn)過,很多同學(xué)恐怕要懵逼了...

Extension

這個特性第一次知道,是我在學(xué)習(xí)OC語言的時候,他和OC語言中的概念Category是相同的。因此,如果你是從OC陣營轉(zhuǎn)換過來的話,這對你來說應(yīng)該也不陌生。這個特性是我最喜歡的特性之一,但對于Kotlin新手來說應(yīng)該算是最難掌握的特性之一了,尤其是在配合Lambda表達(dá)式一起使用的時候,常常會讓新手同學(xué)云里霧里,摸不清頭腦。這個知識點的基本語法很簡單,這里就不贅述了,想要徹底弄懂這個特性,請參看我的另一篇文章Lambda and Extension

反射語法

這也是Kotlin新手經(jīng)常迷惑的一個問題,Kotlin語言針對反射有自己的解決方案,所有反射的對應(yīng)類名前面均添加了K以和Java語言區(qū)分開來。

在Android開發(fā)中,我們經(jīng)常要通過Intent啟動Activity,看一下Java語言中的寫法:

Intent intent = new Intent(this , MainActivity.class);
startActivity(intent);

這在Kotlin語言中,必須這樣寫:

val intent = Intent(this , MainActivity::class.java)
startActivity(intent)

原因很簡單,::class返回的是KClass對象,只有調(diào)用.java才能轉(zhuǎn)換成Java語言的Class對象。這個地方在Android開發(fā)中經(jīng)常用到,這里的使用方法可以先記住,后面慢慢理解Kotlin語言的反射和Java的反射有什么不同。

== 或 ===

在Java語言中,判斷兩個對象是否完全相等(即是否在同一個地址上)使用==,判斷兩個對象的值是否相等使用equals方法進(jìn)行處理,如果你要實現(xiàn)自己的相等邏輯則需要重寫equals方法。而在Kotlin語言中,Kotlin編譯器并不推薦我們使用equals方法,你應(yīng)該經(jīng)常會看到編譯器在你使用equals方法的地方置灰,提示你寫法并不推薦。

這里其實也是一個非常容易讓人混淆的地方,Kotlin語言中的==就等同于Java語言中的equals,而===才是判斷兩個對象地址是否相等的正確操作符。這里一定要切記。

操作符重載

一定有人會奇怪,為什么==的意義和Java語言中的不一樣了,道理其實很簡單,Kotlin語言支持操作符重載。通過操作符重載可以對某個操作符賦予不一樣的意義,簡化代碼邏輯。這里后續(xù)我會專門寫一篇文章來講解這個知識點,關(guān)于這個知識點的具體介紹請先參看官方文檔。

不過,操作符重載在日常開發(fā)中并不常遇到,只是碰到類似的問題一定要明白為什么會這樣。

object

這和Java的基類Object完全不是一回事,這里的object是聲明一個實實在在的堆對象的意思,在什么地方會使用到呢?其實依然非常常見!

在日常Android開發(fā)中,我們常常會遇到一些事件監(jiān)聽器,如果事件監(jiān)聽器只有一個方法,Kotlin編譯器會提示你轉(zhuǎn)換為Lambda表達(dá)式,而如果監(jiān)聽器有多個編譯器,就無法轉(zhuǎn)換成Lambda表達(dá)式了。這個時候問題來了,怎么創(chuàng)建匿名內(nèi)部類呢?糟糕了,Kotlin語言并不支持直接創(chuàng)建匿名內(nèi)部類!??!

怎么辦呢?聰明的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()
            }
        }

關(guān)于Kotlin語言的語法還很多,這篇文章僅僅介紹一些對于Kotlin新手比較棘手的幾個問題,建議新同學(xué)收藏這篇文章,在遇到不知所措的問題的時候,來即時查閱,如果找不到你想要查閱的內(nèi)容,請在評論下方告訴我!

歡迎加入Kotlin交流群

如果你也喜歡Kotlin語言,歡迎加入我的Kotlin交流群: 329673958 ,一起來參與Kotlin語言的推廣工作。

最后,祝大家新年快樂,心想事成!有錢的捧個錢場,沒錢的捧個人場!謝謝大家!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容