對(duì)于Kotlin的一次小調(diào)研

對(duì)Kotlin的一次小調(diào)研

本文主要內(nèi)容

1,Kotlin簡單介紹一下

2,Android Developer意見了解一下

3,Android Stuido Kotlin Plugins環(huán)境搭建及配置

4,Kotlin常見語法糖(這個(gè)糖有點(diǎn)兒甜)

5,Kotlin與Java的相互調(diào)用

1,什么是Kotlin

Kotlin 是一個(gè)基于 JVM 的新的編程語言,由 JetBrains 開發(fā)罕扎。
Kotlin可以編譯成Java字節(jié)碼秃流,也可以編譯成JavaScript稚新,方便在沒有JVM的設(shè)備上運(yùn)行碉纳。
JetBrains镇草,作為目前廣受歡迎的Java IDE IntelliJ 的提供商乘凸,在 Apache 許可下已經(jīng)開源其Kotlin 編程語言橘券。
Kotlin已正式成為Android官方支持開發(fā)語言茉稠。
(節(jié)選自百度百科)

2,Android Developer關(guān)于Kotlin的看法

此前,我在"開源中國"上看到過一篇關(guān)于國外Developer對(duì)于Kotlin的看法的文章,感覺里面很多大神分析的挺有道理的,雖然是基于Kotlin早起的版本,但是其中的一些觀點(diǎn)挺值得我們?nèi)チ私庖幌?

17 位谷歌 Android 開發(fā)專家是如何看待 Kotlin 的描馅?

(不知道為什么link的鏈接被簡書添加了 link.jianshu.com導(dǎo)致無法跳轉(zhuǎn),地址如下:
https://www.oschina.net/news/85468/what-do-17-google-developers-experts-for-kotlin)

但是,我們是在國內(nèi),更多的時(shí)候要考慮國內(nèi)Developer的一些看法,對(duì)此,我請(qǐng)教了技術(shù)群中的一些朋友,他們其中有的人正在用,有的人正在考慮用,有的人在觀望,以下,是他們的一些看法,考慮到隱私相關(guān),涉及到公司名稱部分的已經(jīng)隱去,排名不分先后

深圳市Android開發(fā)工程師-Arthas·李(謹(jǐn)慎觀望):
我覺得吧,相比Java而言,代碼更簡潔,清晰,會(huì)有一陣子的新鮮,但是實(shí)際上.只是非常少一部分人會(huì)用吧。?也許再過個(gè)一年半載,熱度就下去了,具體要看谷歌爸爸給不給力推而线。

廣州市Android開發(fā)工程師-Terenas Menethil 顏(看好):
Kotlin能簡化大量的無用代碼铭污,有效的避免的空指針恋日。
代碼可讀性高,方便了團(tuán)隊(duì)成員維護(hù)嘹狞,降低了成本岂膳。
計(jì)劃在下個(gè)項(xiàng)目中引用,但是還是要看實(shí)際情況(人員,三方庫支持)。

上海市Android開發(fā)工程師-flyinbed(在用)
Kotlin具有現(xiàn)代化靜態(tài)編程語言的很多特點(diǎn)磅网,并大大的減少了重復(fù)代碼谈截,提高了編程效率,讓代碼邏輯更加清晰涧偷。
我就覺得 Java 這樣“冗長”的語言應(yīng)該慢慢退出歷史舞臺(tái)了簸喂,本來幾行代碼就能寫出了邏輯,換成java可以寫出20多行左右燎潮。
歷史的巨輪滾滾向前喻鳄,終究我們編碼會(huì)是越來越簡潔,工作量越來越少确封。

3 AS Kotlin Plusgins配置

(基于AS 3.0+)

①新建項(xiàng)目:

直接選中include Kotlin support即可


image.png

一路Next->Finish之后,就可以看到新建的MainActivity已經(jīng)是.kt格式了


image.png

②已有Java項(xiàng)目的轉(zhuǎn)換

直接在Tools菜單中config

image.png

選中對(duì)應(yīng)的module或All modules


image.png

IDE會(huì)自動(dòng)生成對(duì)應(yīng)的code(module中的.gradlew也會(huì)自動(dòng)配置)

image.png

更簡單的做法
直接在java code下創(chuàng)建一個(gè).kt文件,AS會(huì)提示需要configure,之后的流程就跟之前一樣


image.png

image.png

③java文件轉(zhuǎn)換成kotlin文件

AS中,自帶了可以轉(zhuǎn)換.java文件到.kt文件的插件,部分Java代碼是可以直接通過這個(gè)轉(zhuǎn)換替換成.kt的Code,但是,其中也會(huì)有很多坑,需要具體情況具體分析才行


image.png

④查看Kotlin代碼生成的字節(jié)碼文件和編譯成的.java文件(僅供參考)

image.png
image.png

點(diǎn)擊即可生成.java文件(反編譯得到,有時(shí)候看不懂Kotlin代碼可以參考一下)

4 Kotlin常見方言

①不再需要的findViewById

告別findViewById,kotlin會(huì)自動(dòng)生成View相關(guān)的code(名稱為布局的id),不再需要我們手動(dòng)findViewById了(實(shí)現(xiàn)可看反編譯的.java文件),同時(shí)點(diǎn)擊變量可以自動(dòng)跳轉(zhuǎn)到布局,不局限于Activity,自定義View中也可以這樣使用

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        main_btn_hw.setOnClickListener(this)
        main_btn_basic1.setOnClickListener(this)
        main_btn_basic2.setOnClickListener(this)

    }

②更靈活的字符串

直接通過$號(hào)引用屬性或${}區(qū)間引用對(duì)象方法,通過反編譯代碼可以看到,這一實(shí)現(xiàn)過程的拼接是通過StringBuild實(shí)現(xiàn),不需要擔(dān)心產(chǎn)生額外多的對(duì)象問題

  fun visibleStrCode() {
        val a = "a"
        val b = "b"
        val c = "c"
        val d = "d"

        val v = arrayListOf<String>()

        val alphabet = "a : $a -b : $b - c : $c - d : $d -- ${returnStr()}"

        val sizeStr = "size is ${v.size}"

    }

③Null Pointer Exception

只要一個(gè)對(duì)象或變量沒有被顯式的聲明可以為null,那么之后所有null的賦值都被視作是非法的,無法通過編譯,對(duì)非null值做判空,會(huì)有warning提示

 fun visibleNPEMethod() {
        var nullA2: A? = null
        var notNullA1 = A()

        notNullA1 = nullA2 //不可被賦予一個(gè)null對(duì)象
        notNullA1 = null      //不可賦值為null
        if(notNullA1 == null){//warning
        }
        println(notNullA1.myStr)
        //使用一個(gè)null對(duì)象,需要顯式的做空判斷,否則會(huì)視作是非法的,無法通過編譯
        println(nullA2.myStr)

        //可以通過字面值? Elvis 運(yùn)算符來表示,賦值給一個(gè)不能為null的屬性,
        //在此時(shí)要顯示指定一個(gè)默認(rèn)值
        //賦值給一個(gè)不能為null的值,
        val a3: A = nullA2 ?: A()
        //但是不能這樣訪問屬性
        val str: String = nullA2?.myStr : "null"
        //!! 忽略這個(gè)空判斷,有空指針危險(xiǎn)
        val str2 : String = nullA2!!.myStr

        //判空后會(huì)視作不為null的對(duì)象
        if (nullA2 != null) {
            println(nullA2.myStr)
            //①
            if (nullA2 != null) {//后續(xù)無需判空,會(huì)有warning警告
                //do something
            }
            //②使用let函數(shù),這樣保證其中不為null
            nullA2.let {
                //這里it指向的就是nullA2
                it.myStr
            }
        }
    }

對(duì)于一個(gè)可能為null的對(duì)象,在上面的代碼,是有一些需要注意的細(xì)節(jié)

④更方便的類型轉(zhuǎn)換

is 關(guān)鍵字,當(dāng)某個(gè)對(duì)象通過is關(guān)鍵字進(jìn)行類型判斷后,可以在之后的區(qū)間內(nèi)直接當(dāng)做對(duì)應(yīng)對(duì)象類型做處理,例如使用相關(guān)的方法
搭配When關(guān)鍵字會(huì)更好用

 fun classCastMethod(superClz: SuperClz) {
        when (superClz) {
            is A -> {
                superClz.getA()
            }
            is B -> superClz.getB()
            is C -> superClz.getC()
        }

        if (superClz is A) {
            superClz.getA()
        }
    }

這里的ABC,分別是一個(gè)類,類中獨(dú)有的方法就是getX()

⑤更實(shí)用的Bean(data數(shù)據(jù)類)

使用data關(guān)鍵字修飾的class類
會(huì)自動(dòng)生成set,get,copy,equals等方法
不用再像java一樣顯式的重寫
同時(shí)還可以方便的使用組成方法
當(dāng)然,如果有需求也可以重寫進(jìn)行覆蓋

data class Thai(val name: String, var sex: Int)

就這樣一個(gè)簡單的類,在我們使用可以很方便的獲取一些信息:

    @Test
    fun testDataClz() {
        val man = 1
        val woMan = 2
        val unknow = 3
        //有一個(gè)泰國人,性別男
        var aTiChaSir = Thai("阿提查*春娜依", man)
        //轉(zhuǎn)換一下
        val aTiChaLady = aTiChaSir.copy(sex = woMan)
        //快速獲取屬性
        val (name1, sex1) = aTiChaLady//這里獲取的屬性不是通過名字,而是屬性順序
        println("sex:$name1 --name:$sex1")
    }

⑥延遲加載lazy

Kotlin允許對(duì)一個(gè)屬性進(jìn)行延遲加載,使用by操作符+lazy函數(shù)可以進(jìn)行
值得注意的是,這一操作只允許對(duì)val修飾的屬性
可選:可以指定是否線程安全(默認(rèn))
NOTE:PUBLICATION:允許多個(gè)結(jié)果的可能返回,但只取第一個(gè)結(jié)果

        //延遲加載,必須是val修飾
        //只會(huì)執(zhí)行一次,
        //可選:線程是否安全
        val lazyStr: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
            println("lazy init method")
            "I'm a lazyStr"
        }

Test結(jié)果:

    @Test
    fun testLazyMethod() {
        println(ClassCastClz.lazyStr)
        println(ClassCastClz.lazyStr)
    }
image.png

⑦With關(guān)鍵字,更方便的方法調(diào)用

使用該關(guān)鍵字可以在一定區(qū)間,可以很方便的調(diào)用該對(duì)象的方法和屬性,就像在這個(gè)方法中一樣

    @Test
    fun testKeywordWith() {

        val withClzObj = KeyWith()

        with(withClzObj) {

            println(numberProperty + 100)

            preper()
            onCreate()
            onStart()
            onResume()
        }
    }

⑧l(xiāng)ambda表達(dá)式

     fun lambdaMethod() {
            //顯式指定名稱
            val viewClickListener = View.OnClickListener {
//                myView: View? -> //可選,重寫對(duì)應(yīng)的參數(shù),指定名稱,默認(rèn)為it
//                if(myView != null){
//                    println(myView.id)
//                }
                println(it.id)
            }

            //不指定名稱,交給編譯器去解析
            val anonymityClickListener = { v: View? ->
                if (v != null) {
                    println(v.id)
                }
            }
            val v = View(null)
            v.setOnClickListener(anonymityClickListener)
        }
    }

這里用View.onClickListener做示例
主要寫法有兩種,?①顯式的指定lambad表達(dá)式類型
②交給編譯器去推斷,需要注意的是,交給編譯期,需要參數(shù)對(duì)應(yīng),類型一致否則無法正確的解析

⑨類擴(kuò)展方法

Kotlin支持對(duì)一個(gè)類進(jìn)行額外的方法拓展,這使得你在使用該類可以不用再創(chuàng)建額外的子類來擴(kuò)展其方法,無縫使用,更方便(當(dāng)然,也支持類的屬性擴(kuò)展)
接收者是可以為?,表示可以為null的類型,這樣的話,在設(shè)計(jì)擴(kuò)展方法時(shí),能有更靈活的code編寫
我這里寫了幾個(gè)簡單的栗子

/**
 * 拿到文本的高度
 */
fun TextView.getTextHeight(): Float {
    //可以直接獲取到該類的屬性
    val fontMetrics = paint.fontMetrics
    return fontMetrics.bottom - fontMetrics.top;
}

/**
 * 字符串是否是null
 */
fun String?.isNullStr(): Boolean {
    return this == null || "" == this || "null" == this
}

/**
 * 集合是否是空
 */
fun List<*>?.isNullEmpty(): Boolean {
    return this == null || this.isEmpty()
}

/**
 * 通過Context直接拿Dimension
 */
fun Context.getDimension(resId : Int):Float{
    return this.resources.getDimension(resId)
}

5,Kotlin與Java代碼的相互調(diào)用

這可是Kotlin的一大賣點(diǎn)!!!
這里簡單介紹一下Java調(diào)用Kotlin,前文中Kotlin調(diào)用Java已經(jīng)出現(xiàn)過很多次,不再累贅了
基本可以做到無縫調(diào)用
但是值得注意的是,在java代碼中調(diào)用Kotlin代碼,部分特性會(huì)不再支持
比如:空安全

    public void method() {
        //擴(kuò)展方法可以直接看做一個(gè) static final修飾的方法
        boolean isNull = ExtendMethodListKt.isNullStr("aabb");

        //對(duì)象可以直接創(chuàng)建
        LambdaClaz ccc = new LambdaClaz();

        //調(diào)用屬性需要調(diào)用對(duì)應(yīng)的set,get方法
        View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        };
        ccc.setMyClickListener(clickListener);
        View.OnClickListener runnableInherit = ccc.getMyClickListener();

        //伴生對(duì)象可以直接看做一個(gè)靜態(tài)對(duì)象
        LambdaClaz.Companion.lambdaMethod();
    }

6小結(jié)

以上就是我這段時(shí)間關(guān)于Kotlin的一次小小的調(diào)查,文中很多代碼比較簡單,隨心寫的一些code,就沒有傳項(xiàng)目到GitHub上了,如果有所疑問,歡迎在評(píng)論區(qū)中留言探討.

對(duì)于Kotlin,我個(gè)人的看法:
五級(jí)評(píng)分,Level4,看好,如果在項(xiàng)目有機(jī)會(huì),我會(huì)考慮使用

畢竟,2017年java最好的插件就是Kotlin了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末除呵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子爪喘,更是在濱河造成了極大的恐慌竿奏,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腥放,死亡現(xiàn)場(chǎng)離奇詭異泛啸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)秃症,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門候址,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人种柑,你說我怎么就攤上這事岗仑。” “怎么了聚请?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵荠雕,是天一觀的道長。 經(jīng)常有香客問我驶赏,道長炸卑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任煤傍,我火速辦了婚禮盖文,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蚯姆。我一直安慰自己五续,他們只是感情好洒敏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疙驾,像睡著了一般凶伙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上它碎,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天镊靴,我揣著相機(jī)與錄音,去河邊找鬼链韭。 笑死偏竟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的敞峭。 我是一名探鬼主播踊谋,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼旋讹!你這毒婦竟也來了殖蚕?” 一聲冷哼從身側(cè)響起泰偿,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤磅叛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后因苹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鞭呕,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛤育,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葫松。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓦糕。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腋么,靈堂內(nèi)的尸體忽然破棺而出咕娄,到底是詐尸還是另有隱情,我是刑警寧澤珊擂,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布圣勒,位于F島的核電站,受9級(jí)特大地震影響摧扇,放射性物質(zhì)發(fā)生泄漏圣贸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一扳剿、第九天 我趴在偏房一處隱蔽的房頂上張望旁趟。 院中可真熱鬧昼激,春花似錦庇绽、人聲如沸锡搜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耕餐。三九已至,卻和暖如春辟狈,著一層夾襖步出監(jiān)牢的瞬間肠缔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工哼转, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留明未,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓壹蔓,卻偏偏與公主長得像趟妥,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佣蓉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • 前言 人生苦多披摄,快來 Kotlin ,快速學(xué)習(xí)Kotlin勇凭! 什么是Kotlin疚膊? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,211評(píng)論 9 118
  • Google在今年的IO大會(huì)上宣布,將Android開發(fā)的官方語言更換為Kotlin虾标,作為跟著Google玩兒An...
    藍(lán)灰_q閱讀 76,880評(píng)論 31 489
  • 外婆家的老屋沒有了 老屋后面的樹還在 歷經(jīng)風(fēng)雨淬煉 遒勁挺拔 枝繁葉茂 站在樹下 任潔白的雪花飄落在我的發(fā)梢寓盗、臉頰...
    萬物心同閱讀 147評(píng)論 0 1
  • 你有沒有感覺到,越大越怕冷了呢璧函?盡管我們才二十幾歲贞让,還是最美好的年紀(jì),還是最能折騰的年紀(jì)…… “多穿點(diǎn)吧柳譬,別凍著喳张,...
    夜闌珊閱讀 422評(píng)論 0 1