Kotlin基礎(chǔ)篇

Kotlin簡(jiǎn)介

Kotlin來(lái)源于一個(gè)島嶼的名字,全稱(chēng)是Kotlin Island,是英語(yǔ)【科特林島】之意酥郭,這個(gè)小島位于俄羅斯的圣彼得堡附近。之所以要命名為Kotlin愿吹,是因?yàn)镵otlin的主要開(kāi)發(fā)工作就是由位于圣彼得堡分公司團(tuán)隊(duì)完成的不从。Kotlin是由JetBrains公司開(kāi)發(fā)與設(shè)計(jì)的。

早在2011年犁跪,JetBrains就公布了Kotlin的第一個(gè)版本椿息,并在2012年將其開(kāi)源歹袁。

2016年,Kotlin發(fā)布了1.0的正式版本寝优,并在自家IDE開(kāi)發(fā)工具中加入了對(duì)Kotlin的支持条舔。

2017年,Google宣布Kotlin正式成為Android一級(jí)開(kāi)發(fā)語(yǔ)言乏矾,Android Studio也加入了對(duì)Kotlin的支持孟抗。

兩年之后,Google又在2019年的I/O大會(huì)上宣布钻心,Kotlin已經(jīng)成為Android的第一開(kāi)發(fā)語(yǔ)言凄硼。

在開(kāi)發(fā)Kotlin之前,JetBrains團(tuán)隊(duì)一直使用Java來(lái)創(chuàng)建他們的IDE以及使用Java進(jìn)行業(yè)務(wù)邏輯開(kāi)發(fā)捷沸。之所以開(kāi)發(fā)Kotlin摊沉,是因?yàn)镴etBrains 的工程師們?cè)谑褂肑ava開(kāi)發(fā)應(yīng)用程序的過(guò)程中,發(fā)現(xiàn)了大量的問(wèn)題亿胸。為了提升開(kāi)發(fā)效率以及解決使用Java開(kāi)發(fā)帶來(lái)的問(wèn)題坯钦,在借鑒了其他語(yǔ)言后,他們決定開(kāi)發(fā)一款致力于解決Java問(wèn)題的編程語(yǔ)言Kotlin侈玄。JetBrains深知開(kāi)發(fā)者的需求和痛處婉刀,在孜孜不倦地為開(kāi)發(fā)者提供最實(shí)用、最高效的IDE的同時(shí)序仙,也為開(kāi)發(fā)者提供全新的編程語(yǔ)言以解決目前的技術(shù)問(wèn)題突颊。

或許你會(huì)產(chǎn)生一些疑惑:Android操作系統(tǒng)明明是由Google開(kāi)發(fā)的,為什么JetBrains作為一個(gè)第三方公司潘悼,卻能夠自己設(shè)計(jì)出一門(mén)編程語(yǔ)言來(lái)開(kāi)發(fā)Android應(yīng)用程序呢律秃?

先大概熟悉一下Java語(yǔ)言的運(yùn)行機(jī)制。編程語(yǔ)言大致可以分為兩類(lèi):編譯型語(yǔ)言和解釋型語(yǔ)言治唤。編譯型語(yǔ)言的特點(diǎn)是編譯器會(huì)將我們編寫(xiě)的源代碼一次性地編譯成計(jì)算機(jī)可識(shí)別的二進(jìn)制文件棒动,然后計(jì)算機(jī)直接執(zhí)行,像C和C++都屬于編譯型語(yǔ)言宾添。

解釋型語(yǔ)言則完全不一樣船惨,它有一個(gè)解釋器,在程序運(yùn)行時(shí)缕陕,解釋器會(huì)一行行地讀取我們編寫(xiě)的源代碼粱锐,然后實(shí)時(shí)地將這些源代碼解釋成計(jì)算機(jī)可識(shí)別的二進(jìn)制數(shù)據(jù)后再執(zhí)行,因此解釋型語(yǔ)言通常效率會(huì)差一些扛邑,像Python和JavaScript都屬于解釋型語(yǔ)言怜浅。

那Java是屬于編譯型語(yǔ)言還是解釋型語(yǔ)言呢?

雖然Java代碼確實(shí)是要先編譯再運(yùn)行的蔬崩,但是Java代碼編譯之后生成的并不是計(jì)算機(jī)可識(shí)別的二進(jìn)制文件恶座,而是一種特殊的class文件搀暑,這種class文件只有Java虛擬機(jī)才能識(shí)別,而這個(gè)Java虛擬機(jī)擔(dān)當(dāng)?shù)钠鋵?shí)就是解釋器的角色奥裸,它會(huì)在程序運(yùn)行時(shí)將編譯后的class文件解釋成計(jì)算機(jī)可識(shí)別的二進(jìn)制數(shù)據(jù)

后再執(zhí)行险掀,因此,準(zhǔn)確來(lái)講湾宙,Java屬于解釋型語(yǔ)言樟氢。了解了Java語(yǔ)言的運(yùn)行機(jī)制之后,可以看出侠鳄,其實(shí)Java虛擬機(jī)并不直接和你編寫(xiě)的Java代碼打交道埠啃,而是和編譯之后生成的class文件打交道。那么如果開(kāi)發(fā)了一門(mén)新的編程語(yǔ)言伟恶,然后自己做了個(gè)編譯器碴开,讓它將這門(mén)新語(yǔ)言的代碼編譯成同樣規(guī)格的

class文件,Java虛擬機(jī)能不能識(shí)別呢博秫?沒(méi)錯(cuò)潦牛,這其實(shí)就是Kotlin的工作原理了。Java虛擬機(jī)不關(guān)心class文件是從Java編譯來(lái)的挡育,還是從Kotlin編譯來(lái)的巴碗,只要是符合規(guī)格的class文件,它都能識(shí)別即寒。也正是這個(gè)原因橡淆,JetBrains才能以一個(gè)第三方公司的身份設(shè)計(jì)出一門(mén)用來(lái)開(kāi)發(fā)Android應(yīng)用程序的編程語(yǔ)言。

下面數(shù)據(jù)是來(lái)對(duì)比kotlin和C++在不同的長(zhǎng)度運(yùn)算過(guò)程的耗時(shí)情況:

算式 kotlin耗時(shí) C++耗時(shí)
2組 【9個(gè)9】相乘 6ms 1ms
10組【9個(gè)9】相乘 17ms 10ms
100組 【9個(gè)9】相乘 288ms 25ms
1000組【9個(gè)9】相乘 95171ms 237ms

在此應(yīng)用場(chǎng)景下母赵,C++算法明顯優(yōu)于Kotlin逸爵,效率提升明顯。因?yàn)镃++是編譯型的凹嘲,直接將源碼編譯成機(jī)器代碼师倔,可以直接運(yùn)行;而Kotlin是解釋型周蹭,源碼被編譯成二進(jìn)制字節(jié)碼趋艘,但不是機(jī)器可以識(shí)別的語(yǔ)言,由虛擬機(jī)解釋才能執(zhí)行谷醉,效率會(huì)慢一些。

Kotlin的優(yōu)勢(shì)

Kotlin的語(yǔ)法簡(jiǎn)潔冈闭,同樣的功能俱尼,Kotlin開(kāi)發(fā)的代碼量可能會(huì)比Java少50%,可能更多萎攒。

Kotlin增加了很多高級(jí)語(yǔ)言的很特性遇八,大大的提高了開(kāi)發(fā)效率矛绘。

Kotlin和Java100%兼容,Kotlin可直接調(diào)用Java編寫(xiě)的代碼刃永,也可以無(wú)縫使用Java第三方的開(kāi)源庫(kù)货矮,使得Kotlin在加入新特性的同時(shí),繼承了Java的全部財(cái)富斯够。

Kotlin基礎(chǔ)語(yǔ)法

變量

val(value):不可變變量囚玫,它的值在初始化以后就無(wú)法再次修改,相當(dāng)于java中final變量

var(variable):可變變量读规,對(duì)應(yīng)java中的普通變量

基礎(chǔ)類(lèi)型

Type Bit width 備注
Double 64 Kotlin沒(méi)有double
Float 32 Kotlin沒(méi)有float
Long 64 Kotlin沒(méi)有l(wèi)ong
Int 32 kotlin沒(méi)有int/Integer
Short 16 kotlin沒(méi)有short
Char 16 Kotlin沒(méi)有char
Byte 8 Kotlin沒(méi)有byte
Boolean 8 Kotlin沒(méi)有boolean

基礎(chǔ)類(lèi)型抓督,包含我們常見(jiàn)的數(shù)字類(lèi)型,布爾類(lèi)型束亏,字符類(lèi)型铃在,及這些類(lèi)型組成的數(shù)組,這些常遇到的概念碍遍,統(tǒng)一歸納為基礎(chǔ)類(lèi)型

從上圖也可以看出定铜,在Kotlin語(yǔ)言體系中,是沒(méi)有原始類(lèi)型這個(gè)概念的怕敬,這就意味著揣炕,在Kotlin中,一切都是對(duì)象赖捌。

對(duì)比后祝沸,從某種程度上講,Java的類(lèi)型系統(tǒng)并不是完全面向?qū)ο蟮脑奖樱驗(yàn)樗嬖谠碱?lèi)型罩锐,而原始類(lèi)型并不屬于對(duì)象,而Kotlin則不一樣卤唉,它從語(yǔ)言設(shè)計(jì)的層面就規(guī)避了這個(gè)問(wèn)題涩惑,類(lèi)型系統(tǒng)是完全面向?qū)ο蟮摹?/p>

空安全

Kotlin強(qiáng)制要求開(kāi)發(fā)者在定義變量的時(shí)候,就指定這個(gè)變量是否可能為null桑驱,對(duì)于可能為null的變量竭恬,我們需要在聲明的時(shí)候,在變量類(lèi)型后面加一個(gè)問(wèn)號(hào)“?”

val i: Double = null // 編譯器報(bào)錯(cuò)
 
val j: Double? = null // 編譯通過(guò)

數(shù)字類(lèi)型

val i = 1

val l = 1234567L

val d = 13.14

val f = 13.14F

val hex = 0xAF

val b = 0b01010101

整數(shù)默認(rèn)會(huì)被推導(dǎo)為“Int”類(lèi)型熬的;

Long 類(lèi)型痊硕,我們則需要使用“L”后綴;小

數(shù)默認(rèn)會(huì)被推導(dǎo)為“Double”押框,我們不需要使用“D”后綴岔绸;

Float 類(lèi)型,我們需要使用“F”后綴;

使用“0x”盒揉,來(lái)代表十六進(jìn)制字面量晋被;

使用“0b”,來(lái)代表二進(jìn)制字面量刚盈。

對(duì)于數(shù)字類(lèi)型的轉(zhuǎn)換羡洛,Kotlin與Java的轉(zhuǎn)換行為是不一樣的,Java可以隱式轉(zhuǎn)換數(shù)字類(lèi)型藕漱,而Kotlin更推崇顯示轉(zhuǎn)換欲侮,在一些嚴(yán)謹(jǐn)?shù)倪壿嬇袛嘀校龅揭恍┻吔鐥l件問(wèn)題谴分,隱式轉(zhuǎn)換會(huì)因存在精度問(wèn)題而導(dǎo)致的一些Bug不容易被排除出來(lái)锈麸。而在Kotlin中,提供了toLong()牺蹄,toByte()忘伞、toShort()、toInt()沙兰、toLong()氓奈、toFloat()、toDouble()鼎天、toChar()等舀奶,使得代碼可讀性更強(qiáng),也易維護(hù)斋射。

布爾類(lèi)型

兩種值育勺,true和false,布爾類(lèi)型是支持一些邏輯操作的罗岖,如下:

“&”代表“與運(yùn)算”涧至;

“|”代表“或運(yùn)算”;

“!”代表“非運(yùn)算”桑包;

“&&”和“||”分別代表它們對(duì)應(yīng)的“短路邏輯運(yùn)算”

val i = 1

val j = 2

val k = 3

val isTrue: Boolean = i < j && j < k

字符:Char

Char用于代表單個(gè)字符南蓬,‘A’、’B’哑了、’C’赘方、寫(xiě)法和Java類(lèi)似

字符串:String

val s = "Hello Kotlin!"

寫(xiě)法和Java類(lèi)似,但是Kotlin提供了非常簡(jiǎn)潔的字符串模板:

val name = "Kotlin"

print("Hello $name!")
/*         ↑
    直接在字符串中訪(fǎng)問(wèn)變量
*/

// 輸出結(jié)果:
Hello Kotlin!

當(dāng)然弱左,在Java中也能實(shí)現(xiàn)窄陡,但需要使用“+”進(jìn)行拼接,在字符串格式相對(duì)復(fù)雜的情況下啊拆火,代碼就會(huì)顯得很臃腫跳夭。

如果需要在字符串中引用更加復(fù)雜的變量鳖悠,則需要使用花括號(hào)括起來(lái):

val array = arrayOf("Java", "Kotlin")

print("Hello ${array.get(1)}!")
/*            ↑
      復(fù)雜的變量,使用${}
*/

// 輸出結(jié)果:
Hello Kotlin!

此外优妙,Kotlin還新增了原始字符串,是用三個(gè)引號(hào)來(lái)表示憎账,可用來(lái)存放復(fù)雜發(fā)多行文本套硼,打印格式和定義格式保持同步:

val s = """
            原始字符串
         所見(jiàn)即所得。 """
println(s)

數(shù)組

在Kotlin中胞皱,一般會(huì)使用arrayOf()來(lái)創(chuàng)建數(shù)組邪意,括號(hào)當(dāng)中可以用于傳遞數(shù)組元素進(jìn)行初始化,同時(shí)反砌,Kotlin編譯器也會(huì)根據(jù)傳入的參數(shù)進(jìn)行類(lèi)型推導(dǎo):

val arrayInt = arrayOf(1, 2, 3)

val arrayString = arrayOf("apple", "pear")

如上雾鬼,arrayInt的類(lèi)型會(huì)被推導(dǎo)為整形數(shù)組,arrayString會(huì)被推導(dǎo)為字符串?dāng)?shù)組宴树。

獲取數(shù)組長(zhǎng)度方式和一些操作和集合類(lèi)似:

val array = arrayOf("apple", "pear")

println("Size is ${array.size}")

println("First element is ${array[0]}")

// 輸出結(jié)果:
Size is 2
First element is apple

函數(shù)聲明

在Kotlin中策菜,函數(shù)的聲明和Java不太一樣:

/*

關(guān)鍵字 函數(shù)名  參數(shù)類(lèi)型     返回值類(lèi)型

 ↓   ↓     ↓        ↓      */

fun helloFunction(name: String): String {

    return "Hello $name !"

}
/*   ↑
   花括號(hào)內(nèi)為:函數(shù)體
*/

1)使用了fun關(guān)鍵字來(lái)定義函數(shù)

2)函數(shù)名稱(chēng),駝峰命名規(guī)則

3)是以 (name: String) 這樣的形式傳遞的酒贬,這代表了參數(shù)類(lèi)型為 String 類(lèi)型

4)返回值類(lèi)型又憨,跟在參數(shù)后面

5)函數(shù)體(業(yè)務(wù)邏輯)

如果函數(shù)體只有一行代碼,這種情況下锭吨,其實(shí)可以省略函數(shù)體的花括號(hào)蠢莺,直接使用“=”來(lái)連接,將其變成一種類(lèi)似變量賦值函數(shù)的形式:

fun helloFunction(name: String): String = "Hello $name !"

這種寫(xiě)法零如,稱(chēng)之為 單一表達(dá)式函數(shù)躏将,其中“retuen”是需要去掉的

繼續(xù)簡(jiǎn)化,由于Kotlin是支持類(lèi)型推導(dǎo)的考蕾,返回值的類(lèi)型可省略:

fun helloFunction(name: String) = "Hello $name !"

代碼極其簡(jiǎn)潔祸憋,Kotlin的優(yōu)勢(shì)不僅僅體現(xiàn)在函數(shù)聲明上,在函數(shù)調(diào)用的地方辕翰,它也有很多獨(dú)到之處夺衍。

函數(shù)調(diào)用

代碼風(fēng)格基本和Java一致

helloFunction("Kotlin")

但Kotlin提供了一些新的特性,命名參數(shù)喜命」瞪常可以理解為:就是它允許我們?cè)谡{(diào)用函數(shù)的時(shí)候傳入“形參的名字”

helloFunction(name = "Kotlin")

fun createUser(

    name: String,

    age: Int,

    gender: Int,

    friendCount: Int,

    feedCount: Int,

    likeCount: Long,

    commentCount: Int

) {
    //..
}

// Java調(diào)用方式:
createUser("Tom", 30, 1, 78, 2093, 10937, 3285)

// Kotlin調(diào)用方式:
createUser(

    name = "Tom",

    age = 30,

    gender = 1,

    friendCount = 78,

    feedCount = 2093,

    likeCount = 10937,

    commentCount = 3285

)

可以看到,把函數(shù)的形參加了進(jìn)來(lái)壁榕,形參和實(shí)參通過(guò)“=”連接矛紫,建立了兩者的對(duì)應(yīng)關(guān)系,其實(shí)這樣代碼的可讀性會(huì)更強(qiáng)牌里。

此外颊咬,Kotlin還支持參數(shù)默認(rèn)值:

fun createUser(

    name: String,

    age: Int,

    gender: Int = 1,

    friendCount: Int = 0,

    feedCount: Int = 0,

    likeCount: Long = 0L,

    commentCount: Int = 0

) {
    //..
}

createUser(

    name = "Tom",

    age = 30,

    commentCount = 3285

)

以上方法調(diào)用時(shí)只傳了三個(gè)參數(shù)务甥,剩余的參數(shù)沒(méi)有傳,但是Kotlin編譯器會(huì)自動(dòng)幫忙填充默認(rèn)值

但在Java中喳篇,需要定義三個(gè)參數(shù)的重載方法敞临,才能實(shí)現(xiàn)。其實(shí)麸澜,在一些場(chǎng)景下還是提高了開(kāi)發(fā)效率的挺尿。

流程控制

在Kotlin中,流程控制主要有if炊邦,when编矾,for,white馁害,這些語(yǔ)句可以控制代碼的執(zhí)行流程窄俏,具體如下:

if

if 語(yǔ)句,在程序中主要用于邏輯判斷碘菜,和Java基本一致凹蜈,此外,還可以作為表達(dá)式來(lái)使用:

val i = 1

val message = if (i > 0) "Big" else "Small"

print(message)

//輸出結(jié)果:
Big

另外忍啸,在Kotlin中明確規(guī)定了類(lèi)型分為可空類(lèi)型和不可空類(lèi)型踪区,會(huì)遇到一些可空的變量,判斷是否為空:

fun getLength(text: String?): Int {

  return if (text != null) text.length else 0

}

類(lèi)似這種邏輯判斷出現(xiàn)的很頻繁吊骤,為此缎岗,Kotlin提供了一種簡(jiǎn)寫(xiě),稱(chēng)之為Elvis表達(dá)式

fun getLength(text: String?): Int {

  return text?.length ?: 0

}
when

when 語(yǔ)句白粉,在程序當(dāng)中也是主要用于邏輯判斷的传泊,當(dāng)代碼邏輯只有兩個(gè)分支的時(shí)候,一般用if/else鸭巴,而大于兩個(gè)邏輯分支的時(shí)候眷细,一般使用when:

val i: Int = 1

when(i) {

    1 -> print("一")

    2 -> print("二")

    else -> print("i 不是一也不是二")

}

// 輸出結(jié)果:
一

when語(yǔ)句和Java中的switch case語(yǔ)句很像,不過(guò)Kotlin的when更加強(qiáng)大鹃祖,同時(shí)可以作為表達(dá)式溪椎,為變量賦值:

val i: Int = 1

val message = when(i) {

    1 -> "一"

    2 -> "二"

    else -> "i 不是一也不是二" // 如果去掉這行,會(huì)報(bào)錯(cuò)

}

print(message)

循環(huán)遍歷 while恬口,for

while語(yǔ)法和Java類(lèi)似校读,不做過(guò)多講解

Kotlin在for循環(huán)做了大幅度調(diào)修改,Java中最常用的for-i循環(huán)在kotlin中直接被舍棄了祖能,而Java中另外一種for-each循環(huán)則被Kotlin進(jìn)行了加強(qiáng)歉秫,變成了for-in循環(huán)。

val array = arrayOf(1, 2, 3)

for (i in array) {

    println(i)

}

此外养铸,Kotlin還支持迭代一個(gè)區(qū)間雁芙。

在Kotlin中用關(guān)鍵字 .. 來(lái)創(chuàng)建一個(gè)兩端閉區(qū)間轧膘,兩邊指定區(qū)間的左右端點(diǎn):

val range = 0..10 // 代表 [0, 10]

可通過(guò)for-in來(lái)遍歷這個(gè)區(qū)間:

for (i in range){

   printIn(i)

}

在很多時(shí)候,需要?jiǎng)?chuàng)建單閉區(qū)間兔甘,可通過(guò)until關(guān)鍵字來(lái)創(chuàng)建一個(gè)左閉右開(kāi)的區(qū)間:

val range = 0 until 10 // 代表 [0, 10)

默認(rèn)情況下谎碍,for-in循環(huán)每次執(zhí)行循環(huán)時(shí)會(huì)在區(qū)間范圍內(nèi)遞增1,即i++的效果洞焙,如果想跳過(guò)某一些元素椿浓,可以使用step關(guān)鍵字:

for(i in range step 2){

  printIn(i)

}
// 打印:0 2 4 6 8

相當(dāng)于在遍歷range區(qū)間時(shí)闽晦,每次遞增2,即可i=i+2的效果提岔。

不管是..仙蛉,還是until關(guān)鍵字都要求區(qū)間的左端小于等于區(qū)間的右端,即這兩個(gè)關(guān)鍵字創(chuàng)建的都是一個(gè)升序區(qū)間碱蒙,如果想創(chuàng)建一個(gè)降序區(qū)間荠瘪,可使用downTo關(guān)鍵字:

for (i in 6 downTo 0 step 2) {

    println(i)

}

// 輸出結(jié)果:
6 4 2 0

類(lèi)與對(duì)象

在Kotlin中也是使用class關(guān)鍵字來(lái)聲明一個(gè)類(lèi)的,這一點(diǎn)和Java是保持一致的赛惩。

class Person{

     var name = “”

     var age = 0

      fun eat(){
        printIn(name + “is eating. He is ”+age +” years old.”)
            }
}

對(duì)這個(gè)類(lèi)進(jìn)行實(shí)例化:

val p = Person()

Kotlin實(shí)例化一個(gè)類(lèi)的方式和Java基本類(lèi)似哀墓,只是去掉了new關(guān)鍵字。

繼承

我們先定義一個(gè)Student類(lèi):

class Student{

   var sno =””

    var grade = 0

}

怎么讓Student繼承Person呢喷兼?

在Kotlin中任何一個(gè)非抽象類(lèi)默認(rèn)是不可以被繼承的篮绰。相當(dāng)于Java中給類(lèi)聲明了final。之所以這么設(shè)計(jì)季惯,其實(shí)和val關(guān)鍵字的原因是差不多的吠各,類(lèi)和變量一樣,最好是不可變的勉抓。

如果需要被繼承贾漏,在Person類(lèi)前面加上open關(guān)鍵字即可:

open class Person{

}

加上open關(guān)鍵字之后,就是在主動(dòng)告知Kotlin編譯器藕筋,Person這個(gè)類(lèi)時(shí)專(zhuān)門(mén)為繼承而設(shè)計(jì)的纵散,它就會(huì)被允許繼承。

在Java中繼承的關(guān)鍵字是extends隐圾,而在Kotlin中變成了一個(gè)冒號(hào):

class Student : Person(){

    var sno = “”

    var grade = 0

}

接口

一般會(huì)在接口中定義一系列的抽象行為伍掀,然后由具體的類(lèi)去實(shí)現(xiàn)。

Java中實(shí)現(xiàn)接口使用的是關(guān)鍵字implements暇藏,而Kotlin中統(tǒng)一使用冒號(hào)硕盹,中間用逗號(hào)進(jìn)行分隔。

class Student(name:String,age int):Person(name,age),Study{

   override fun doHomework(){

    }

}

修飾符

Kotlin中也有四種叨咖,public瘩例,private啊胶,protected 和internal

區(qū)別在于:在Java中默認(rèn)的是default,而Kotlin中public是默認(rèn)修飾符垛贤。

權(quán)限跟Java稍微有出入:

protected: Java中表示對(duì)當(dāng)前類(lèi)焰坪,子類(lèi)和同一個(gè)包路徑下的類(lèi)可見(jiàn)。在Kotlin表示只對(duì)當(dāng)前類(lèi)和子類(lèi)可見(jiàn)聘惦。

internal:只對(duì)同一個(gè)模塊的類(lèi)可見(jiàn)某饰,。如:開(kāi)發(fā)了一個(gè)模塊給別人使用善绎,但一些函數(shù)只允許在模塊內(nèi)部調(diào)用黔漂,不想暴露在外部,可以用internal來(lái)聲明禀酱。

修飾 Java Kotlin
public 所有類(lèi)可見(jiàn) 所有類(lèi)可見(jiàn)(默認(rèn))
private 當(dāng)前類(lèi)可見(jiàn) 當(dāng)前類(lèi)可見(jiàn)
protected 當(dāng)前類(lèi)炬守,子類(lèi)和同一個(gè)包路徑下的類(lèi)可見(jiàn) 只對(duì)當(dāng)前類(lèi)和子類(lèi)可見(jiàn)
default 同一個(gè)包路徑下面的類(lèi)可見(jiàn)(默認(rèn)) 無(wú))
internal 無(wú) 同一個(gè)模塊中的類(lèi)可見(jiàn)

數(shù)據(jù)類(lèi)和單列類(lèi)

數(shù)據(jù)類(lèi)通常需要重寫(xiě)equals(),hashCode().toStirng()這幾個(gè)方法,其中equals()用于判斷兩個(gè)數(shù)據(jù)類(lèi)是否相等剂跟,這些方法會(huì)讓代碼顯得比較臃腫减途,有些時(shí)候卻又不得不寫(xiě)。但在Kotlin中曹洽,這種情況就變得極其簡(jiǎn)單鳍置,可通過(guò)data關(guān)鍵字來(lái)聲明


data class CellPhone(val brand:String,val price:Double)

當(dāng)在一個(gè)類(lèi)的前面聲明了data關(guān)鍵字時(shí),就表明它是一個(gè)數(shù)據(jù)類(lèi)送淆,Kotlin會(huì)根據(jù)主構(gòu)造函數(shù)中的參數(shù)自動(dòng)生成equals()税产,hashCode(),toString()等固定方法偷崩,一定程度上減少了工作量砖第。

最后再講一個(gè)Kotlin中的單例類(lèi)

在java中寫(xiě)單例的常規(guī)寫(xiě)法,首先為了進(jìn)制外部創(chuàng)建Singleton的實(shí)例环凿,需要用private關(guān)鍵字將Singleton的構(gòu)造函數(shù)私有化梧兼,然后給外部提供一個(gè)getInstance()靜態(tài)方法用于獲取Singleton的實(shí)例。在getInstance()方法中判斷當(dāng)前緩存的Singleton實(shí)例為null智听,就創(chuàng)建一個(gè)新的實(shí)例羽杰,否則直接返回緩存的實(shí)例。

然而到推,在Kotlin中考赛,會(huì)將一些固定的,重復(fù)的邏輯實(shí)現(xiàn)了隱藏莉测,只暴露一個(gè)最簡(jiǎn)單的用法颜骤。在Kotlin中創(chuàng)建單例,只需要將class關(guān)鍵字改為object關(guān)鍵字即可捣卤。Kotlin會(huì)自動(dòng)一個(gè)Singleton實(shí)例忍抽,且會(huì)保證全局只會(huì)存在一個(gè)Singleton實(shí)例八孝。

小結(jié)

Kotlin 和 Java 的語(yǔ)法很像,但在一些細(xì)節(jié)之處鸠项,Kotlin 總會(huì)有一些新的東西干跛。熟悉完基礎(chǔ)語(yǔ)法之后,我們可以來(lái)看看 Kotlin 在這方面都做了以下改進(jìn):

  • 支持類(lèi)型推導(dǎo)祟绊;

  • 代碼末尾不需要分號(hào)楼入;

  • 字符串模板;

  • 原始字符串牧抽,支持復(fù)雜文本格式嘉熊;

  • 單一表達(dá)式函數(shù),簡(jiǎn)潔且符合直覺(jué)扬舒;

  • 函數(shù)參數(shù)支持默認(rèn)值阐肤,替代 Builder 模式的同時(shí),可讀性還很強(qiáng)呼巴;

  • if 和 when 可以作為表達(dá)式。

同時(shí)御蒲,JetBrains 也非常清楚開(kāi)發(fā)者在什么情況下容易出錯(cuò)衣赶,所以,它在語(yǔ)言層面也做了很多改進(jìn):

  • 強(qiáng)制區(qū)分“可為空變量類(lèi)型”和“不可為空變量類(lèi)型”厚满,規(guī)避空指針異常府瞄;

  • 推崇不可變性(val),對(duì)于沒(méi)有修改需求的變量碘箍,IDE 會(huì)智能提示開(kāi)發(fā)者將“var”改為“val”遵馆;

  • 基礎(chǔ)類(lèi)型不支持隱式類(lèi)型轉(zhuǎn)換,這能避免很多隱藏的問(wèn)題丰榴;

  • 數(shù)組訪(fǎng)問(wèn)行為與集合統(tǒng)一货邓,不會(huì)出現(xiàn) array.length、list.size 不統(tǒng)一的情況四濒;

  • 函數(shù)調(diào)用支持命名參數(shù)换况,提高可讀性,在后續(xù)維護(hù)代碼的時(shí)候不易出錯(cuò)盗蟆;

  • when 表達(dá)式戈二,強(qiáng)制要求邏輯分支完整,盡可能的減少了邏輯上的漏洞

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喳资,一起剝皮案震驚了整個(gè)濱河市觉吭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仆邓,老刑警劉巖鲜滩,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴鳖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡绒北,警方通過(guò)查閱死者的電腦和手機(jī)黎侈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)闷游,“玉大人峻汉,你說(shuō)我怎么就攤上這事∑晖” “怎么了休吠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)业簿。 經(jīng)常有香客問(wèn)我瘤礁,道長(zhǎng),這世上最難降的妖魔是什么梅尤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任柜思,我火速辦了婚禮,結(jié)果婚禮上巷燥,老公的妹妹穿的比我還像新娘赡盘。我一直安慰自己,他們只是感情好缰揪,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布陨享。 她就那樣靜靜地躺著,像睡著了一般钝腺。 火紅的嫁衣襯著肌膚如雪抛姑。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天艳狐,我揣著相機(jī)與錄音定硝,去河邊找鬼。 笑死毫目,一個(gè)胖子當(dāng)著我的面吹牛喷斋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蒜茴,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼星爪,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了粉私?” 一聲冷哼從身側(cè)響起顽腾,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后抄肖,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體久信,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年漓摩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了裙士。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡管毙,死狀恐怖腿椎,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夭咬,我是刑警寧澤啃炸,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站卓舵,受9級(jí)特大地震影響南用,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜掏湾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一裹虫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧融击,春花似錦筑公、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涩拙。三九已至际长,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間兴泥,已是汗流浹背工育。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搓彻,地道東北人如绸。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像旭贬,于是被迫代替她去往敵國(guó)和親怔接。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容