一、介绍

        如今在Android开发中,应用层开发语言主要是Java和Kotlin,Kotlin是后来加入的,主导的语言还是Java。kotlin的加入仿佛让会kotlin语言的开发者更屌一些,其实不然。

        有人说kotlin的引入是解决开发者复杂的逻辑,并且对空指针控制的比较友好,但是我们在开发过程中会发现,好像并不是这么回事,甚至有些开发者发现,在使用过程中会出现莫名其妙的错误,而且还不好定位。

        这时候,我们应该去分析,kotlin适不适合自己,自己能不能驾驭?

二、分析Java与kotlin实战中的利与弊

        学过政治都知道,任何东西都是一把双刃剑,既有好的一面也有不好的一面。不能什么都照搬过来。kotlin的好是建立在你已很好的掌握,但是不好的是你如果只会基础,在使用过程中,无法避免一些异常情况。但是Java的友好是适合新手使用,普及度高。

kotlin的弊端与分析

1、参数为null

参数为null这种很容易引起空指针,为什么会出现这种情况?是受Java的写法有关系
Java:
public void log(String txt)
Kotlin:
public fun log(txt:String)

正常Java你是可以传null进去,但是在kotlin,你传null就会报错

 分析:

Java中,你参数可以传任何,你传null也是没问题,但是你在kotlin中,就没有这么随意了,这是为什么呢?

 在kotlin中,任何参数都会被修饰,为空或者不为空,默认是NotNull。如果你不能传递null值过去。

如何避免?

只要我们是通过kotlin语法,你在任何参数申明都需要设置成为可为null

public fun log(txt:String?)

这个时候,在参数中,已变成可为null。

2、lateinit 报错未初始化先使用

        lateinit 是稍后初始化,这个只能做全局,不能出现在方法体,但是也有个问题。如果你用lateinit
修饰一个变量,那么这个变量可以不先申明变量值,等使用时再初始化。

但是这个也会出现一个问题,如果你没初始化就使用会报错
lateinit var txt: String public fun log() { println(txt) }

        有人会说,我不能判空嘛?判空也不行。只要你使用之前就必须初始化,否则就会报错。这个问题在新手特别容易犯错。

        所以为什么这个关键字往往出现在修饰View的初始化使用比较多。这个在使用的时候进行判空,所以该字段默认为null,但是你使用必须要有值,只要你调用get方法就会触发。

思考:

有人会问,如果我直接修改变量的get方法,如果为null,那么get直接给他初始化。

 lateinit不允许修改set和get。

        但是Java就不会,Java是所见即所得,你的东西就是你的东西,kotlin是通过自己的语言限制,翻译成Java语言。所以,你不了解或者说不清楚目标类,很容易造成风险,并且这种bug被带到线上概率很大

3、参数类型强转"!!"导致null空指针

这种错误在方法调用很容易出现,而且这种BUG的概率非常高,导致项目质量很差。

public fun log(txt:String)

分析:

我们申请一个方法,参数不为null,在Java过程中,这种你不需要管,直接调用,一般对null的判断会在方法体中进行
Java:
public void log(String txt){

if(txt!=null){}

}

但是你在kotlin中,只能在调用处进行判断,否则就要将参数通过强制表示不为null,"!!"

我们在项目中进程遇到log(msg!!)这种错误的写法,这种写法,如果你的实参申请可以为null,但是形参不能为null,这个时候你只能通过"!!"来强转,但是:你的实参如果为null,这个时候就会报空指针,这是为什么?

这是因为你的实参在调用时已进行强制转换,也会提前进行空指针异常检查,所以在使用 "!!"强转符号时,一定要判空,否则会报错,但是Java中,我们随便传null。

4.形参为Val修饰的常量,无法修改

在kotlin中,形参是传值类型,你是无法直接修改变量,必须通过其他变量接收完再修改

 默认是Val类型
public fun addOne(item:Int):Int{ val relVal=item+1 return relVal }

5.默认为null的变量引用

默认值为null,如果变量已申请为这种,那么你以后的使用将离不开"?"和"!!"转换。

var temp:String?=null

这种区分全局和局部

1、全局:

如果是全局,对于IDE来说,任何时刻都有可能是null,所以在方法中使用,默认当成null来处理

 所以,你即使判空,还是不行。需要一辈子跟着"?"和"!!"搭配使用。

2、局部:

如果是局部,只要你在使用之前判断过一次,在合理的校验范围内都是有效
public fun log(mm:String) { var txt:String?=null if (txt==null) return
txt.length }
就是这种有起义的原因,导致在实战中,很多人很难理解

三、总结

        通过kotlin的自身问题,其实kotlin就是一种插件语言,最终还是翻译成Java,只是目前来看,通过翻译的目标类,还是Java本身,但是增加了特别多的校验,导致写法和Java有很大的不同。这种不同来自我们的习惯问题。有人提前判空,有人喜欢丢在使用出判空,调用处让语法自然一些。

        Android应用不像PC,空指针是致命的BUG,出现一个就会导致崩溃。所以,kotlin对空指针校验特别严格,也对使用埋下了隐患,新手可以绕开校验,但是对于绕开的原理不够理解,就会引起崩溃。

        kotlin也不是一无是处,他更像是一个插件,插件的好处是自然的,可扩展等也是kotlin的自身优势。

        所以,通过上面的分析,大家可以自行去选择项目中的语言,是kotlin还是Java,如果你向往kotlin的写法,那么就得去了解kotlin的原理,以及要改变自己在Java中的开发习惯。kotlin是先判断后使用,而Java写法很随意,由开发者自行定义,kotlin都是翻译好的。

最后,用好可以事半功倍,用不好,会引起各种不好排查的BUG。最后送一句话:水能载舟亦能覆舟。

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信