What
官网
Kotlin由JetBrains负责维护, 在2011年宣布发布, 2012年正式发布第一个版本, 2016年发布1.0版本. 目前最新的版本是1.1.
而JetBrains是IntelliJ IDE的开发商, Android Studio是基于IntelliJ的, 可以说Kotlin就是亲儿子, 有绝对好的IDE支持.
Why
趋势
- Google 宣布官方支持 Kotlin, Android Announces Support for Kotlin
- Android Studio 3.0会内置Kotlin, 在项目中使用Kotlin会非常方便, 而且可以预见未来会有越来越多的支持.
- 社区, 从1.0到现在, Kotlin已经形成了社区, 虽然仍比不上Java, 但是已经有非常多的资源, 现在更是有了Google的支持, 发展的势头只会越来越猛.
- 企业, 已经有Expedia, Flipboard, Pinterest, Square等公司在企业级应用中使用了Kotlin, Kotlin for Android Case Studies中提到3个例子, 有大公司的带头踩坑, 相信能够证明Kotlin可以胜任实际生产的使用.
完美兼容Java
完美兼容的意思是我们可以将Java代码和Kotlin代码混合在一起.
这意味着在Kotlin表现不好的地方, 我们可以保留Java的代码, 在项目中只使用团队认为合适的特性.
同样, 这意味着我们可以局部接入Kotlin而不是一次性把整个项目改头换面.
简洁
Kotlin有非常多的语法糖, 可能有些好用, 有些太过简洁, 但是不可否认, 使用Kotlin可以减少非常多的代码量, 能够提升日??⒌男? 尽管Java有各种各样的IDE插件支持也能实现自动生成代码, 但是一个文件越少内容阅读起来越容易理解不是吗?
功能
虽然Java能够通过插件来避免手动输入代码, 不过有些功能则是Kotlin有而Java没有的.
不是说所有这些新功能都很好, 但是合理使用这些功能特性确实可以简化代码结构和更加方便地实现某些特定需求.
How
资源
官方使用Kotlin开发Android的说明文档
中文版Kolton文档
Kotlin在线编辑器学习
官方书籍: Kotlin In Action, github上正在更新的翻译项目
最吸引的特性
从写代码的角度看, Kotlin比Java好在哪?
永别NPE(NullPointerException)
null
类型在Java中被吐槽了很多年了, 空指针错误也是项目中常见的造成崩溃的异常, Android中一般会使用注解库的@Nullable
和@NonNull
来辅助检查, 不过这依赖于开发者的自觉性, 而这通常很不可靠.
在Kotlin中在语法上区分空和非空
在Java的一个普通方法里面我们要做非空检查, 例如
@Override
public void showMovie(Movie movie) {
if(movie != null) {
mTextView.setText(movie.name);
}
}
而在Kotlin中
// Movie不可能为null
override fun showMovie(movie: Movie) {
mTextView.setText(movie.name)
}
// Movie可能为null
override fun showMovie(movie: Movie?) {
mTextView.setText(movie?.name)
}
在第一情况里面, Movie
不可能为空, 如果调用时传空值, 会发生编译错误.
在第二种情况里面, 只要添加?
就可以传空值, 但是同样不用进行空值判断, 因为movie?.name
在空值的情况下是不会执行.
实际的好处
- 省略了非常多的非空判断
- 从根源上防止了NPE的发生
类型检查和转换
在列表的Adapter里面经常有下面的代码
@Override
public void onBindViewHolder(BaseViewHolder holder, int position) {
if(holder instanceof AHolder) {
((AHolder)holder).textView.setText(null);
((AHolder)holder).imageView.setSelected(true);
}
}
为什么已经有了
instanceof
判断后, 还需要强制转换呢?
连续的强制类型转换会让代码非常长, 进而影响阅读性.
在Koltin中只要
if(holder is AHolder) {
holder.textView.setText(null);
holder.imageView.setSelected(true);
}
编译器会自动帮我们进行转换, 这只是其中一个例子, 在很多地方都可以省略强制类型转换, 使得代码更简介.
命名参数和默认参数
在需要输入大量参数的时候我们一般使用Builder和链式调用, 例如:
new Request.Builder()
.setDomainName("baidu.com")
.setSecondDomainName("tieba")
.setApi("path")
.setFixed(true)
.setIsHttps(false);
当要输入的参数太多, 不可能使用构造函数, 因为不能确定哪些是用户想自定义的, 使用Kotlin则只需要定义一个构造函数包含所有参数, 例如
constructor(port: Int = 8080,
api: String? = null,
secondDomainName: String? = null,
domainName: String? = null,
isHttps: Boolean = false,
isFixed: Boolean = false) {
// 省略赋值
}
// 只赋值部分参数
Request(api = "path", isFixed = true)
不再需要建造者模式, 不再需要链式调用的代码, 同时命名参数指明了参数含义, 代码的可读性没有受到影响.
扩展函数
在我们的代码中经常需要增加工具类来对某些类进行封装方便使用, 例如获取颜色的代码
public static getColor(Context context, int resId) {
return context.getResources().getColor(resId);
}
在Kotlin我们可以选择扩展Int
类型, 而不需要另外建一个工具类
fun Int.toColor(context : Context) : Int = context.resources.getColor(this)
// 调用
R.color.ct_02.toColor(context)
这里的例子可能不是很合适, 但是合理使用扩展函数可以
- 大量减少工具类,
- 让具体的项目可以自行扩展公共的基础库的类, 这样当基础库不能满足项目需要时, 不需要再新建一个名字类似功能类似的新类.
数据对象
项目中会包含非常多的Json映射类, 大量的getter/setter
, toString
方法, 现在Kotlin只需要一个data
关键字就能满足几个IDE插件做的事.
-
equals()
/hashCode()
函数 -
toString()
函数 -
copy()
函数
lambda和函数类型
这两个特性应该不需要举例了, 再也不需要在View#setOnClickedListener
的时候创建监听, 可以大幅减少代码的行数.
函数类型可以减少不必要的接口定义.
其他
-
when
语法取代switch
, 再也不用担心漏掉break
-
[]
可以同时在数组和列表中使用 -
in
表示范围, 不再需要a > 0 && a < 10
, 只要a in 0..10
这里只是一篇小小的总结文章, 还有更多我不熟悉和还没发掘到特性等待你去尝试.
当然, Kotlin也肯定有他不好的地方, 或者有人觉得太过简洁反而不好, 有人觉得Kotlin还太年轻可能到处是坑, 也需要一段时间的学习和适应, 阵痛是肯定会有的, 但是身为程序猿不就是应该为了追求更好更高效率而去踩坑么, 现在有更好的放在你面前, 为什么不试试呢? 毕竟老大们都上了 :D