对于Kotlin的一次小调研

对Kotlin的一次小调研

本文主要内容

1,Kotlin简单介绍一下

2,Android Developer意见了解一下

3,Android Stuido Kotlin Plugins环境搭建及配置

4,Kotlin常见语法糖(这个糖有点儿甜)

5,Kotlin与Java的相互调用

1,什么是Kotlin

Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。
Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。
JetBrains,作为目前广受欢迎的Java IDE IntelliJ 的提供商,在 Apache 许可下已经开源其Kotlin 编程语言。
Kotlin已正式成为Android官方支持开发语言。
(节选自百度百科)

2,Android Developer关于Kotlin的看法

此前,我在"开源中国"上看到过一篇关于国外Developer对于Kotlin的看法的文章,感觉里面很多大神分析的挺有道理的,虽然是基于Kotlin早起的版本,但是其中的一些观点挺值得我们去了解一下.

17 位谷歌 Android 开发专家是如何看待 Kotlin 的?

(不知道为什么link的链接被简书添加了 link.jianshu.com导致无法跳转,地址如下:
https://www.oschina.net/news/85468/what-do-17-google-developers-experts-for-kotlin)

但是,我们是在国内,更多的时候要考虑国内Developer的一些看法,对此,我请教了技术群中的一些朋友,他们其中有的人正在用,有的人正在考虑用,有的人在观望,以下,是他们的一些看法,考虑到隐私相关,涉及到公司名称部分的已经隐去,排名不分先后

深圳市Android开发工程师-Arthas·李(谨慎观望):
我觉得吧,相比Java而言,代码更简洁,清晰,会有一阵子的新鲜,但是实际上.只是非常少一部分人会用吧。�也许再过个一年半载,热度就下去了,具体要看谷歌爸爸给不给力推。

广州市Android开发工程师-Terenas Menethil 颜(看好):
Kotlin能简化大量的无用代码,有效的避免的空指针。
代码可读性高,方便了团队成员维护,降低了成本。
计划在下个项目中引用,但是还是要看实际情况(人员,三方库支持)。

上海市Android开发工程师-flyinbed(在用)
Kotlin具有现代化静态编程语言的很多特点,并大大的减少了重复代码,提高了编程效率,让代码逻辑更加清晰。
我就觉得 Java 这样“冗长”的语言应该慢慢退出历史舞台了,本来几行代码就能写出了逻辑,换成java可以写出20多行左右。
历史的巨轮滚滚向前,终究我们编码会是越来越简洁,工作量越来越少。

3 AS Kotlin Plusgins配置

(基于AS 3.0+)

①新建项目:

直接选中include Kotlin support即可


image.png

一路Next->Finish之后,就可以看到新建的MainActivity已经是.kt格式了


image.png

②已有Java项目的转换

直接在Tools菜单中config

image.png

选中对应的module或All modules


image.png

IDE会自动生成对应的code(module中的.gradlew也会自动配置)

image.png

更简单的做法
直接在java code下创建一个.kt文件,AS会提示需要configure,之后的流程就跟之前一样


image.png

image.png

③java文件转换成kotlin文件

AS中,自带了可以转换.java文件到.kt文件的插件,部分Java代码是可以直接通过这个转换替换成.kt的Code,但是,其中也会有很多坑,需要具体情况具体分析才行


image.png

④查看Kotlin代码生成的字节码文件和编译成的.java文件(仅供参考)

image.png
image.png

点击即可生成.java文件(反编译得到,有时候看不懂Kotlin代码可以参考一下)

4 Kotlin常见方言

①不再需要的findViewById

告别findViewById,kotlin会自动生成View相关的code(名称为布局的id),不再需要我们手动findViewById了(实现可看反编译的.java文件),同时点击变量可以自动跳转到布局,不局限于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)

    }

②更灵活的字符串

直接通过$号引用属性或${}区间引用对象方法,通过反编译代码可以看到,这一实现过程的拼接是通过StringBuild实现,不需要担心产生额外多的对象问题

  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

只要一个对象或变量没有被显式的声明可以为null,那么之后所有null的赋值都被视作是非法的,无法通过编译,对非null值做判空,会有warning提示

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

        notNullA1 = nullA2 //不可被赋予一个null对象
        notNullA1 = null      //不可赋值为null
        if(notNullA1 == null){//warning
        }
        println(notNullA1.myStr)
        //使用一个null对象,需要显式的做空判断,否则会视作是非法的,无法通过编译
        println(nullA2.myStr)

        //可以通过字面值? Elvis 运算符来表示,赋值给一个不能为null的属性,
        //在此时要显示指定一个默认值
        //赋值给一个不能为null的值,
        val a3: A = nullA2 ?: A()
        //但是不能这样访问属性
        val str: String = nullA2?.myStr : "null"
        //!! 忽略这个空判断,有空指针危险
        val str2 : String = nullA2!!.myStr

        //判空后会视作不为null的对象
        if (nullA2 != null) {
            println(nullA2.myStr)
            //①
            if (nullA2 != null) {//后续无需判空,会有warning警告
                //do something
            }
            //②使用let函数,这样保证其中不为null
            nullA2.let {
                //这里it指向的就是nullA2
                it.myStr
            }
        }
    }

对于一个可能为null的对象,在上面的代码,是有一些需要注意的细节

④更方便的类型转换

is 关键字,当某个对象通过is关键字进行类型判断后,可以在之后的区间内直接当做对应对象类型做处理,例如使用相关的方法
搭配When关键字会更好用

 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,分别是一个类,类中独有的方法就是getX()

⑤更实用的Bean(data数据类)

使用data关键字修饰的class类
会自动生成set,get,copy,equals等方法
不用再像java一样显式的重写
同时还可以方便的使用组成方法
当然,如果有需求也可以重写进行覆盖

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

就这样一个简单的类,在我们使用可以很方便的获取一些信息:

    @Test
    fun testDataClz() {
        val man = 1
        val woMan = 2
        val unknow = 3
        //有一个泰国人,性别男
        var aTiChaSir = Thai("阿提查*春娜依", man)
        //转换一下
        val aTiChaLady = aTiChaSir.copy(sex = woMan)
        //快速获取属性
        val (name1, sex1) = aTiChaLady//这里获取的属性不是通过名字,而是属性顺序
        println("sex:$name1 --name:$sex1")
    }

⑥延迟加载lazy

Kotlin允许对一个属性进行延迟加载,使用by操作符+lazy函数可以进行
值得注意的是,这一操作只允许对val修饰的属性
可选:可以指定是否线程安全(默认)
NOTE:PUBLICATION:允许多个结果的可能返回,但只取第一个结果

        //延迟加载,必须是val修饰
        //只会执行一次,
        //可选:线程是否安全
        val lazyStr: String by lazy(LazyThreadSafetyMode.PUBLICATION) {
            println("lazy init method")
            "I'm a lazyStr"
        }

Test结果:

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

⑦With关键字,更方便的方法调用

使用该关键字可以在一定区间,可以很方便的调用该对象的方法和属性,就像在这个方法中一样

    @Test
    fun testKeywordWith() {

        val withClzObj = KeyWith()

        with(withClzObj) {

            println(numberProperty + 100)

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

⑧lambda表达式

     fun lambdaMethod() {
            //显式指定名称
            val viewClickListener = View.OnClickListener {
//                myView: View? -> //可选,重写对应的参数,指定名称,默认为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表达式类型
②交给编译器去推断,需要注意的是,交给编译期,需要参数对应,类型一致否则无法正确的解析

⑨类扩展方法

Kotlin支持对一个类进行额外的方法拓展,这使得你在使用该类可以不用再创建额外的子类来扩展其方法,无缝使用,更方便(当然,也支持类的属性扩展)
接收者是可以为?,表示可以为null的类型,这样的话,在设计扩展方法时,能有更灵活的code编写
我这里写了几个简单的栗子

/**
 * 拿到文本的高度
 */
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代码的相互调用

这可是Kotlin的一大卖点!!!
这里简单介绍一下Java调用Kotlin,前文中Kotlin调用Java已经出现过很多次,不再累赘了
基本可以做到无缝调用
但是值得注意的是,在java代码中调用Kotlin代码,部分特性会不再支持
比如:空安全

    public void method() {
        //扩展方法可以直接看做一个 static final修饰的方法
        boolean isNull = ExtendMethodListKt.isNullStr("aabb");

        //对象可以直接创建
        LambdaClaz ccc = new LambdaClaz();

        //调用属性需要调用对应的set,get方法
        View.OnClickListener clickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {

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

        //伴生对象可以直接看做一个静态对象
        LambdaClaz.Companion.lambdaMethod();
    }

6小结

以上就是我这段时间关于Kotlin的一次小小的调查,文中很多代码比较简单,随心写的一些code,就没有传项目到GitHub上了,如果有所疑问,欢迎在评论区中留言探讨.

对于Kotlin,我个人的看法:
五级评分,Level4,看好,如果在项目有机会,我会考虑使用

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 210,978评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,954评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,623评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,324评论 1 282
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,390评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,741评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,892评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,655评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,104评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,569评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,254评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,834评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,725评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,950评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,260评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,446评论 2 348

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,734评论 25 707
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,161评论 9 118
  • Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿An...
    蓝灰_q阅读 76,788评论 31 489
  • 外婆家的老屋没有了 老屋后面的树还在 历经风雨淬炼 遒劲挺拔 枝繁叶茂 站在树下 任洁白的雪花飘落在我的发梢、脸颊...
    万物心同阅读 143评论 0 1
  • 你有没有感觉到,越大越怕冷了呢?尽管我们才二十几岁,还是最美好的年纪,还是最能折腾的年纪…… “多穿点吧,别冻着,...
    夜闌珊阅读 415评论 0 1