說(shuō)在前面
從上一篇我們了解了 kotlin 這門語(yǔ)言,以及通過(guò) IntelliJ IDEA 和 AndroidStudio 開發(fā)工具創(chuàng)建了 kotlin 項(xiàng)目并運(yùn)行了 “hello world” 程序,在這一篇,我們將來(lái)學(xué)習(xí) kotlin的數(shù)據(jù)類型系統(tǒng)矛物,以及各種類型之間的轉(zhuǎn)換。
1. Java 類型系統(tǒng)
由上圖可知:在 Java 中,類型系統(tǒng)由8種基本類型钾挟,6種引用類型以及一種空特殊的空引用類型。
基本類型:byte,char,short,long,float,double,int,boolean
-
引用類型:
類:class
接口:interface
數(shù)組:array
參數(shù)化類型:泛型
注解:Annotation
枚舉:enumeration
空引用:null
基本數(shù)據(jù)類型和引用數(shù)據(jù)類型在創(chuàng)建的時(shí)候饱岸,內(nèi)存的存儲(chǔ)方式區(qū)別:
基本數(shù)據(jù)類型:在被創(chuàng)建時(shí)掺出,在棧上給其劃分一塊內(nèi)存徽千,將數(shù)值 直接存儲(chǔ)在棧上(性能高);
引用數(shù)據(jù)類型:在被創(chuàng)建時(shí)汤锨,首先在棧上給其引用(句柄)分配 一塊內(nèi)存双抽,而對(duì)象的具體信息存儲(chǔ)在堆內(nèi)存上,然后由棧上面 的引用指向堆中對(duì)象的地址闲礼。
2.kotlin 類型系統(tǒng)
在 kotlin 中牍汹,將類型系統(tǒng)根據(jù)數(shù)據(jù)是否可空分為了可空類型和不可空類型〖碓螅可空類型能夠在編譯程序的時(shí)候進(jìn)行類型檢查慎菲,以提前發(fā)現(xiàn)并解決問(wèn)題,大大的降低了出現(xiàn)空指針的情況锨并。
2.1 不可空類型
kotlin 中不可空的數(shù)字類型對(duì)應(yīng)了 Java 中的原始類型露该,但是寫法卻 不一樣:
- Kotlin中的數(shù)字類型與 Java 原始的數(shù)字類型
// 聲明Int 型
val age:Int=20
//聲明Long 型
val along:Long=12368172397127391
//聲明 Float 型
val aFloat:Float=2.0F
//聲明 double 型
val aDouble:Double=3.0
//聲明 Short 型
val aShort:Short=127
// 聲明Byte 型
val maxByte: Byte = Byte.MAX_VALUE
//聲明Boolean
val aBoolean: Boolean = true
以上都是不可空的數(shù)字類型,在聲明變量的時(shí)候都給它們賦了值琳疏,但是如果我們不給它賦值或者賦值為空有决,則編譯器會(huì)顯示錯(cuò)誤,提醒我們必須要初始化該數(shù)字類型的值空盼。
-
Kotlin中可空數(shù)字類型與 Java 中裝箱數(shù)字類型
Snipaste_2020-02-17_10-31-55.png
Snipaste_2020-02-17_10-31-55.png
2.2 可空類型
在Java 開發(fā)中书幕,經(jīng)常會(huì)遇到空指針的問(wèn)題,那么能不能在編譯的時(shí)候提前發(fā)現(xiàn)錯(cuò)誤并進(jìn)行代碼修復(fù)呢揽趾?kotlin中出現(xiàn)了可空類型以解決這個(gè)痛點(diǎn)台汇。我們以如下輸出字符串str的長(zhǎng)度代碼為例:
- kotlin中:
val str:String? ="hello world"
fun getLength():Int{
return str?.length?:0
}
fun main(args: Array<String>) {
println("str字符串的長(zhǎng)度為:${getLength()}")
}
- Java代碼:
public class helloword {
static String str = "hello world";
public static void main(String[] args) {
System.out.print("str 字符串的長(zhǎng)度為:" + getLength());
}
public static int getLength() {
if (str != null) {
return str.length();
} else {
return 0;
}
}
}
在kotlin 代碼中 str?.length?:0 就是 kotlin中常用的 Elvis表達(dá)式,它的意思是如果str為不空篱瞎,那就返回 str.length的值苟呐,否則返回0。同樣的需求俐筋,不一樣量的代碼牵素,kotlin是不是顯得更加精簡(jiǎn)全面呢?顯然是的澄者。
2.3 安全操作符
(1)安全調(diào)用符:"?."
val str:String? ="hello world"
fun main(args: Array<String>) {
// 方式一:
if (str != null) {
println(str.length)
}
// 方式二:
println(str?.length)
}
我們知道笆呆,在程序中,不能使用可空的對(duì)象直接調(diào)用其屬性或者方法粱挡,否則會(huì)直接報(bào)錯(cuò)赠幕,在Java 中也會(huì)出現(xiàn)空指針異常。在以上代碼中询筏,在保證程序的正常執(zhí)行的情況下榕堰,方式一和方式二需求一樣,但是方式二使用了安全調(diào)用符 ?.是得代碼更加的簡(jiǎn)潔嫌套。程序只有在str不為空的情況下才會(huì)執(zhí)行 str.length的方法逆屡。
(2)Elvis運(yùn)算符“?:”
在前面例子中 str?.length?:0 就使用了Elvis運(yùn)算符“?:”,同理只有str不為空的情況下才會(huì)執(zhí)行 str.length的方法
(3)非空斷言“!!”
Kotlin中提供了斷言操作符“!!”圾旨,它表示已經(jīng)確定該可空對(duì)象不為空且直接調(diào)用其屬性或方法。該操作符需要謹(jǐn)慎使用康二,因?yàn)橐坏┯龅搅嗽搶?duì)象為空的時(shí)候碳胳,則會(huì)導(dǎo)致空指針異常。代碼及結(jié)果如下:
3.類型檢測(cè)和智能類型轉(zhuǎn)換
3.1 is 和 !is 運(yùn)算符
is運(yùn)算符是用來(lái)檢測(cè)對(duì)象A是否與特定的類型X兼容(此對(duì)象A是X類型或者派生于X類型)
3.2 Java 和kotlin中的類型轉(zhuǎn)換
例子:
現(xiàn)有一個(gè)子類沫勿,一個(gè)父類挨约,子類和父類各自擁有一個(gè)方法
需要實(shí)現(xiàn)父類調(diào)用子類的方法 以及子類調(diào)用父類的方法打印輸出"hello kotlin"
(1)Java 代碼實(shí)現(xiàn)
(2)kotlin代碼實(shí)現(xiàn)
對(duì)比以上代碼可知:Java 中父類在調(diào)用子類方法獲取 “kotlin”字符串的時(shí)候,編譯器中進(jìn)行了強(qiáng)制類型轉(zhuǎn)換产雹,而kotlin 代碼中诫惭,父類直接調(diào)用了子類的getKotlin(),并沒(méi)有進(jìn)行強(qiáng)制類型轉(zhuǎn)換蔓挖,這是因?yàn)榫幾g器已經(jīng)知道它該父類本來(lái)就是子類的實(shí)例夕土,無(wú)需再進(jìn)行強(qiáng)轉(zhuǎn)。
3.3 kotlin中智能類型轉(zhuǎn)換
在kotlin中瘟判,使用 as 進(jìn)行引用類型的顯式類型轉(zhuǎn)換類型轉(zhuǎn)換怨绣,但如果類型轉(zhuǎn)換失敗會(huì)出現(xiàn)類型轉(zhuǎn)換失敗的異常,使用 as拷获?運(yùn)算符進(jìn)行智能類型轉(zhuǎn)換篮撑,當(dāng)轉(zhuǎn)換失敗的時(shí)候直接返回null,代碼如下:
fun main(args: Array<String>) {
val parent: Parent = Parent()
val child: Child? =parent as? Child
println(child?.getKotlin())
}
open class Parent{
fun getHello():String{
return "hello"
}
}
class Child : Parent() {
fun getKotlin(): String {
return "kotlin"
}
}
以上代碼匆瓜,父類轉(zhuǎn)換為子類并調(diào)用其方法赢笨,會(huì)出現(xiàn)類型轉(zhuǎn)換失敗的異常,但是使用了as驮吱?運(yùn)算符茧妒,會(huì)直接輸出null而避免了異常。