Kotlin--阿里一线专家带你探索实践第三十一期
2017年09月20日--2017年09月25日 分享到:

Kotlin作为Android官方支持的开发语言越来越受到程序员的欢迎:简洁的语言、与Java的无缝互译、很棒的IDE支持、且不断进化和对其他语言的思想的借鉴,如果你刚刚从事或者一直从事Android开发,Kotlin都将成为你很好的起点或新的助手。
本期专家问答我们请来了《 Kotlin极简教程 》一书作者 陈光剑 来为大家解答相关问题。

本期问答内容
1.Kotlin 有什么特性?
2.Kotlin 在 Android 中有什么优势?
3.Kotlin 未来发展前景如何?
4.学习 Kotlin 难度怎么样?

作者简介:
陈光剑
这里写图片描述

资深开发人员,目前就职于阿里巴巴集团,参与过多种平台工具的开发,具有丰富的平台开发经验,操练过Java、Android、Scala、Groovy等语言进行领域建模、架构设计、工具开发,在工作中积累了大量经验,善于总结,乐于分享,发布过大量技术文章。

为了营造更好的问答氛围,我们不欢迎一切与主题无关的讨论、灌水。欢迎大家踊跃提问,陈光剑老师会为大家解答问题,并在活动结束后抽取三位幸运用户赠送《 Kotlin极简教程 》实体书一本

这里写图片描述

已结束
本期嘉宾 1505790488 69411 陈光剑 资深开发人员,目前就职于阿里巴巴集团,参与过多种平台工具的开发,具有丰富的平台开发经验,操练过Java、Android、Scala、Groovy等语言进行领域建模、架构设计、工具开发,在工作中积累了大量经验,善于总结,乐于分享,发布过大量技术文章。
2 sd4324530 sd4324530 2017.09.21 11:00提问
Kotlin和Java混合使用的时候很郁闷

Kotlin自身对定义的变量默认为不可空,在纯Kotlin开发的时候确实很舒服,少写很多代码,但是和Java混合开发的时候,最简单的例子,我在Kotlin项目中依赖第三方的java库,调用里面的方法,kotlin貌似默认全部认为方法的返回值都是可空的,导致拿到返回值后继续使用,全部都要判断非空,就算你可以明确知道不可能为空,也要在代码上加上!!来保证接下来可以直接使用。但是在链式调用的时候,非常蛋疼,每一步都要!!,极其难看,对于这个问题,有没有什么好的解决方法呢?

2 universsky2015 universsky2015 2017.09.21 14:52回答

您好!

Kotlin和Java混合使用确实是体验不佳的。没有写纯纯的Kotlin那么爽的。

Kotlin 在设计之初就考虑了与 Java 的互操作性。我们可以从 Kotlin 中自然地调用现存的 Java 代码。

但是,如果,我们在Kotlin中调用Java代码中的丑陋的特性(比如说,null),这确实是不得已的事情。

一下内容摘自《Kotlin极简教程》 10.1.5 小节:

10.1.5 调用来自Java中的null
我们知道Java 中的任何引用都可能是null,这样我们在使用 Kotlin调用来自 Java 的对象的时候就有可能会出现空安全的问题。

平台类型
Java 声明的类型在 Kotlin 中会被特别对待并称为平台类型(platform types )。对这种类型的空检查会放宽,因此它们的安全保证与在 Java 中相同。
请看以下示例:
@RunWith(JUnit4::class)
class CallingJavaNullSafe {
@Test fun testCallingJavaNullSafe() {
val product = Product()
// product.name = null
product.category = "金融财务类"
product.gmtCreated = Date()
product.gmtModified = Date()
println(JSONUtils.toJsonString(product))

    val name = product.name
    println("product name is ${name}")

    val eqName = name == "账务系统"
    println(eqName)

    name.substring(1)
}

}
上面的代码可以正确编译通过。Kotlin编译器对来自Java的空值name(平台类型)放宽了空检查name.substring(1)。但是这样的空指针异常仍然会在运行时抛出来。
运行上面的代码,我们可以看到输出:
{"category":"金融财务类","gmtCreated":1500050426817,"gmtModified":1500050426817}
product name is null
false

null cannot be cast to non-null type java.lang.String
kotlin.TypeCastException: null cannot be cast to non-null type java.lang.String
at com.easy.kotlin.CallingJavaNullSafe.testCallingJavaNullSafe(CallingJavaNullSafe.kt:27)
我们没有设置name的值,在Java它就是null。我们在Kotlin代码中使用了这个name进行计算,我们可以看出:
val eqName = name == "账务系统"
println(eqName)
可以正确输出false。这表明Kotlin的判断字符串是否相等已经对null的情况作了判断处理,这样的代码如果在Java中调用 name.equals("账务系统") 就该抛空指针异常了。
但是当我们直接使用name这个值来调用name.substring(1)的时候,Kotlin编译器不会检查这个空异常,但是运行时还是要报错的:null cannot be cast to non-null type java.lang.String。
如果我们不想看到这样的异常,而是当name是null的时候,安静的输出null,直接使用Kotlin中的空安全的调用 .? :
name?.substring(1)
这样,运行的时候不会抛出异常,直接安静的返回null。
平台类型助记符

平台类型不能在程序中显式表述,因此在语言中没有相应语法。 然而,编译器和 IDE 有时需要(在错误信息中、参数信息中等)显示他们,所以我们用一个助记符来表示他们:
 T! : 表示 T 或者 T?
 (Mutable) Collection! : 表示 “可以可变或不可变、可空或不可空的 T 的 Java 集合”
 Array<(out) T>! : 表示可空或者不可空的 T(或 T 的子类型)的 Java 数组

weixin_37660437
weixin_37660437 厉害了
2 个月之前 回复
2 thepromonkeyof heluo ThePromonkeyOf_HeLuo 2017.09.21 10:58提问
Android程序员如何学习Kotlin?

陈老师,您好。我从事Android一年了,有Java基础。今年I/O大会时就看到了Kotlin的宣传。这几个月以来,在日常的工作之余。我看了一些Kotlin博客,但现在回想起来知识点零碎,分散。陈老师能给一个学习路线的指导嘛?例如:如何入门Kotlin?如何深入学习Kotlin,并将知识应用到项目开发中去?在学习中应重点把握什么?如何更深入的学习Kotlin?

2 universsky2015 universsky2015 2017.09.21 17:54回答

Hi,您好。( 老师,不敢当哦。其实,我也只是个学生。 :)

Kotlin 相当易于学习——Kotlin语法简洁直观,看上去非常像Scala,但更简单。 它不遵循特定的编程哲学,如函数式风格或面向对象风格。

以下内容摘自《Kotlin极简教程》1.2.6 小节:

1.2.6 编程语言学习小结
学习一门语言大概会经历如下几步。
1.基本语法
学习任何东西,都是一个由表及里的过程。学习一门编程语言也一样。对于一门编程语言来说,“表” 就是基本词汇和语法。对于基础语法的学习,我们可以看一些简短而又系统的教程。
2.编码实践
所谓“纸上得来终觉浅,绝知此事要躬行”是也,此处就不多说,总之,要掌握基础,持续练习。
每一门编程语言的学习内容都会涉及:
 运行环境
 数据类型(数字、字符串、数组、集合、映射字典等)
 表达式
 流程控制
 类、方法与函数
等基本内容,不同的语言还有一些不同的特性。我们可以通过对比学习来加深理解,并通过大量实践深入理解,达到熟练使用。后面还要再去深入了解面向对象编程OOP、函数式编程FP、并发、异常、文件IO、网络、标准库等内容,并辅以持续的练习,这些内容才能够让你真正进入编程领域并做出实际的软件。
相信10000小时定律,“No Pain, No Gain。”
学习一门新的语言的时候,要利用以前所学的语言的功底,但是也要保持开放的心态。这些在认知心理学中有相应的讲述。感兴趣的读者可以去了解一下。
3.技近乎道
基础语法学习,能让你快速上手,应用实践。对技巧和坑的关注,一定程度上拓展了你的知识面。系统学习,一方面会进一步拓展你的知识面。另一方面,也有利于你语言知识结构的形成。
任何一门成熟语言,都有其特有的生态。这个生态包括: 框架、扩展包、解决方案、模式、规范等。
在不断编码实践过程中,我们逐步熟练使用很多API库、框架,也不断踩坑填坑、看源代码、不断解决问题,不断加深对语言的理解,同时会看一些优秀的框架源代码。
如果还有精力,我们再去学习语言更底层的东西,而不仅仅停留在应用层面。如Java中的集合类实现的算法与数据结构,如JVM是如何执行Java代码的。如Java的线程和操作系统线程的关系。以及一些操作系统方面的知识。
最后,达到游刃有余的境界。进入这一层级,基本可入武林高手之列了。
《庖丁解牛》中说到:“臣之所好者,道也,进乎技矣。始臣之解牛之时,所见无非牛者。三年之后,未尝见全牛也。方今之时,臣以神遇而不以目视,官知止而神欲行。依乎天理,批大郤,导大窾,因其固然,技经肯綮之未尝,而况大軱乎!”可以将这里的“牛”理解为我们所说的各种编程思想、编程范式、编程方法、编程技巧等等。最后,达到“运用之妙,存乎一心”之境也。
4.创造新世界
“编程的本质就是创造世界。”达到这个境界的,基本都是世界顶尖大牛了。

ThePromonkeyOf_HeLuo
ThePromonkeyOf_HeLuo 一字之师也是师啊!
3 个月之前 回复
2 lucf1103 lucf1103 2017.09.20 16:06提问
Kotlin和Java之间代码转换需要注意啥?

前几天自己也捣鼓了下Kotlin,在studio上下载插件,然后转换之前的代码,
代码看上去是简化了很多,但报错了3个地方,不知道应该怎么改。
记得一个地方是intent跳转 目标Activity的 .class 报错

我主要疑问是如果我一个老的Java项目和新的Kotlin结合,能运行起来吗?

然后使用了那个插件之后,整个AS突然变卡顿了,写入代码后卡3秒每次。

2 universsky2015 universsky2015 2017.09.20 17:31回答

亲,您好。

如果要看具体的问题报错的话,您可以私聊我,把代码地址发我下,我们可以具体一起看下哦。

一个老的Java项目和新的Kotlin结合,能运行起来。这就是混合开发。
“整个AS突然变卡顿了,写入代码后卡3秒每次。” 这个。。可能是插件问题,或者插件集成IDE的问题。重启,试试。

PS: 要是在java中使用 在kotlin中所谓的高级特性是不大推荐的。 混合开发最好是使用kotlin去调java,不推荐用java 去调 kotlin (有不少特性,得使用额外的注解, 有点丑。 向Kotlin迁移吧!)。
在Kotlin于Java的互操作的过程中,还是有些小坑要踩的。

Kotlin 在设计时就考虑了 Java 互操作性。可以从 Kotlin 中自然地调用现存的 Java 代码,并且在 Java 代码中也可以很顺利地调用 Kotlin 代码。
几乎所有 Java 代码都可以使用而没有任何问题。

官网文档是极佳的学习文档:

(a) Kotlin调用Java(推荐,基本无缝调用,从Java平滑迁移Kotlin)
http://kotlinlang.org/docs/reference/java-interop.html

(b) Java调用Kotlin:(你得使用一堆注解,比较丑陋,不推荐了)
http://kotlinlang.org/docs/reference/java-to-kotlin-interop.html

共7条数据 1 3 尾页