对于Kotlin,我一开始是有抵触情绪的,觉得这门语言有点像Js,所以主观地就判定这个语言不好。后面来到新公司,大佬要求新写的代码必须使用Kotlin,于是慢慢喜欢上了这门语言。很多人在学习之前会问,Kotlin到底值不值得学?在这里,我们先不急着回答这个问题,先来看看Kotlin之于Java到底有哪些不一样的地方。
第一,Kotlin对可空类型的显示支持
这一点简单来讲,就是用Kotlin写的代码在编译的时候就能杜绝NullPointerException。用Java进行开发的时候,最头疼的就是NullPointerException,因为这个对于Java而言,这个是运行时异常,不能在编译的期间找出这些可能为null的变量或属性,现在Kotlin做到了,可以这么说,用Kotlin写的代码基本上是不会出现NullPointerException的。
之前我们公司android组内做过一次统计,在我们项目使用Kotlin之前,bugly上面我们的crash里面,出现最多的前10个中,有5个是NullPointerException,前20个中,有12个NullPointerException。而在使用Kotlin之后,出现频率前10个crash中,没有一个NullPointerException,前20个中,只有3个NullPointerException,这三个都是出现在原来的Java代码里面的。这个提升是非常明显的,所以我想说的是,冲着这一点,Kotlin,你值得拥有。
第二,关于kotlin-android-extensions插件
Kotlin不仅在对null类型有很好的处理,在其他很多方面也有很多优势。接下来来看看kotlin-android-extensions这个插件,说的简单点,这个插件能够代替android里面的findViewById操作,通过这个插件,我们可以直接在Activity,Fragment和View中直接通过xml里面的id来找到view对象,再也不需要使用findViewById这样重复的代码来初始化View对象了。虽然android提供了DataBinding机制来方便开发者来初始化View对象,但是DataBinding在apk打包的时候经常报错,相比Kotlin这点,就没有这个问题,而且使用起来更简洁,基本不需要在代码中做任何初始化操作。另外,ButterKnife这类开源控件虽然也能省略findViewById的操作,但仍然需要在代码中使用注解作相应的初始化操作,所以综合来说,还是Kotlin得插件更加好用点,还在等什么呢,赶紧用起来吧。
第三,谈谈Kotlin在实际使用中那些小的细节
Talk is cheap,show me the code . 我来聊聊平时使用Kotlin的一些体会。
(1) apply
首先来看看用Java来创建TextView并设置相关属性
privateTextViewcreateTextView(){
TextView textView =newTextView(this);
textView.setTextAppearance(this,R.style.Text12_Gray);
textView.setBackgroundResource(R.drawable.bg_goods_mark_red_border);
textView.setTextColor(this.getResources().getColor(R.color.mark_red));
textView.getPaint().setTypeface(Typeface.DEFAULT_BOLD);
textView.setSingleLine();
textView.setGravity(Gravity.CENTER);
textView.setEllipsize(TextUtils.TruncateAt.END);
returntextView;
}
对比来看看Kotlin中写法,使用apply,可以使代码更加整洁,apply将new 出来的TextView接收过来设置相关属性,并且最后将这个对象返回。
private funcreateTextView(): TextView {
returnTextView(context).apply{
setTextAppearance(context,R.style.Text12_Gray)
setBackgroundResource(R.drawable.bg_goods_mark_red_border)
setTextColor(Utils.getColor(context,R.color.mark_red))
paint.typeface= Typeface.DEFAULT_BOLD
setSingleLine(true)
gravity= Gravity.CENTER
ellipsize= TextUtils.TruncateAt.END
}
}
(2) let
mData?.let{
...it...
}
let函数只会在mData不为null的时候才会执行lambda,相对于Java中加if判断使用let函数能让我们的代码更简洁。
(3) data class
data classUser(varid: Int, varname: String)
编译器会为数据类(data class)自动生成以下函数:
equals()/hashCode()
toString() 默认输出"User(name=John, age=42)"
componentN() 按声明顺序对应于所有属性
copy() 对应于Java中clone方法,用于对象的拷贝
在java中如果需要上面的方法,我们是需要自己重写的,Kotlin中只用声明data皆可以全部搞定,有没有感觉很爽?
(4) lambda
java监听View的回调如下:
mView.setOnClickListener(newView.OnClickListener() {
@Override
public voidonClick(View v) {
.....
}
});
mView.setOnClickListener{
......
}
Kotlin中使用lambda就可以写得更简洁,Java在1.8上也可以使用了。对于Lambda,远不止替代Java中的匿名内部类那么简单,这一点,将在后面第(6)点来讲。
(5) 扩展函数
//定义成员函数使View的显示和隐藏调用起来更加整洁
funView.hide() {
this.visibility= View.GONE
}
funView.show() {
this.visibility= View.VISIBLE
}
扩展函数算是Kotlin中的一大特色吧,简单来说,就是我们能够给别人的类添加我们自己的方法,如上,我们给View添加了hide和show的方法,添加之后我们能够像调用普通成员函数一样调用这些扩展函数。
(6) 函数式API
了解RxJava的都知道,RxJava中的流式编程风格能够让我们的代码逻辑更加清晰,具有很高的可读性。这里说的函数式API,主要针对的是集合的函数式API,首先来看看下面的代码片段。
valcurrentFilter =
mFilterList.filter{ itisSearchResultFilter}
.map{ itasSearchResultFilter}
.find{ it.id== "1"}
上面展示的是使用Kotlin中函数式API找到集合中对象类型是SearchResultFilter并且它的id是1的元素。看到这段代码有没有觉得不一样,如果我们用java的话肯定是要使用for循环的,但是使用Kotlin中的filter和map这类的函数却能够让我们在某些时候处理集合的时候更容易,而且也让我们的代码可读性更好。
简单说下filter和map函数的作用,filter能够帮我们过滤出满足条件的元素,但是filter并不会改变这些元素,而map可以改变这些元素,map能够将原来的集合按照给定的操作转换后映射到一个新的集合中去。
Kotlin类型的函数还有find,groupBy,flatMap和flatten等等。这里就不一一介绍了。另外,这种函数配合RxJava食用更佳,相信结合RxJava来写代码你会发觉写出优雅地代码并不是想象的那么难。
以上,Kotlin相对于Java以及Kotlin中一些特性简单介绍了下,其实还有很多地方没有说的,这里只是列举了一些开发中使用Kotlin的体会,现在,来回答前面抛出的问题,到底Kotlin是否值得学习,我觉得我应该已经不需要回答了,如果大家做的是android开发的话,墙裂推荐Kotlin,so, just do it !
最好,如果想更系统的学习Kotlin,网站的话我还是推荐Kotlin官方文档,没有比这更好的资料了,如果推荐书籍的话,“Kotlin 实战”还不错。
领取专属 10元无门槛券
私享最新 技术干货