目錄:
1. Kotlin的開(kāi)發(fā)者是誰(shuí)?使用Kotlin開(kāi)發(fā)安卓有哪些好處?
2. Kotlin中的空安全是什么意思?在kotlin中如何處理null異常?
3. 有哪些特性是Kotlin有但Java沒(méi)有的?
4. Kotlin中有哪些構(gòu)造函數(shù)?
5. Kotlin的數(shù)據(jù)類(lèi),以及使用數(shù)據(jù)類(lèi)的注意事項(xiàng)
6. Kotlin中l(wèi)et,run,apply,also,with的區(qū)別
7. 常見(jiàn)Java在Kotlin上的不同實(shí)現(xiàn)
1. Kotlin的開(kāi)發(fā)者是誰(shuí)?使用Kotlin開(kāi)發(fā)安卓有哪些好處?
Kotlin的開(kāi)發(fā)者是JetBrains
使用Kotlin開(kāi)發(fā)的好處在于:
- 對(duì)于Java開(kāi)發(fā)人員來(lái)說(shuō)更好學(xué)易用
- 與Java有互操作性,同個(gè)項(xiàng)目中可以同時(shí)使用Kotlin和Java,使遷移更輕松
- Android JetPack和其他常用的庫(kù)都有支持Kotlin
- 代碼更少,可讀性更強(qiáng)且更安全
- 有成熟的語(yǔ)言和環(huán)境,有大量的社區(qū)支持
- 支持多平臺(tái)開(kāi)發(fā),平臺(tái)之間共享可以公共代碼
2. Kotlin中的空安全是什么意思?在kotlin中如何處理null異常?
null safety的特性是為了去除空指針異常
NullPointerException在實(shí)時(shí)運(yùn)行中的出現(xiàn)風(fēng)險(xiǎn)。也用來(lái)區(qū)分空引用和非空引用。
kotlin用elvis操作符來(lái)處理空異常
// 在Kotlin中定義了可空類(lèi)型和不可空類(lèi)型
var a:String 是不可空類(lèi)型
var b:String? 是可空類(lèi)型
// 如果給不可空類(lèi)型賦值空的話,會(huì)編譯失敗
a.length a=null // 編譯失敗
b.length // 報(bào)異常,變量b可能為空
// 兩種處理方式:
- 安全處理:b?.length?:-1
- 為空時(shí)拋出異常:b!!.length
3. 有哪些特性是Kotlin有但Java沒(méi)有的?
- Elvis操作符:空安全 Null Safety
- 協(xié)程 Coroutines
- Range操作符
- 運(yùn)算符重載 Operator overloading.
- 智能轉(zhuǎn)換 Smart casts.
- 伴生對(duì)象 Companion Object
-
Elvis操作符:用!!或者?來(lái)做空處理 -
Range操作符:用兩個(gè)點(diǎn)確定范圍
如:i in (1..10)
帶索引的:(index,item) in (1..10).withIndex() -
智能轉(zhuǎn)換:在Java中通過(guò)參數(shù)取到一個(gè)Object對(duì)象,不確定類(lèi)型,我們用
instanceOf判斷后,還需要對(duì)其進(jìn)行強(qiáng)轉(zhuǎn)才能調(diào)用該類(lèi)型中的方法,
Kotlin中只需要做了判斷,就不需要再做強(qiáng)轉(zhuǎn) -
伴生對(duì)象:用來(lái)替代Java中的static關(guān)鍵字 -
運(yùn)算符重載:通過(guò)operater關(guān)鍵字,我們可以重載加減乘除等這些運(yùn)算符 -
協(xié)程:一種輕量級(jí)的多線程,本質(zhì)上子程序都是在同一個(gè)線程下執(zhí)行的。
4. Kotlin中有哪些構(gòu)造函數(shù)?
有兩種
- 主構(gòu)造函數(shù) primary構(gòu)造函數(shù)
class 類(lèi)名 constructor(形參1,形參2,形參3){ init{ 初始化代碼塊 } }- 次級(jí)構(gòu)造函數(shù) secondary構(gòu)造函數(shù)。
構(gòu)造函數(shù)定義在類(lèi)體中,類(lèi)似Java
4.1 主構(gòu)造函數(shù)
class 類(lèi)名 constructor(形參1,形參2,形參3){ init{ 初始化代碼塊 } }
原型:
class Person constructor(name : String , age :Int){
private val name : String
private var age : Int
init{
this.name = name
this.age = age
}
}
演變1:當(dāng)constructor沒(méi)有注解和可見(jiàn)性修飾符作用于它時(shí),關(guān)鍵字可隱藏
class Person (name : String , age :Int){
private val name : String
private var age : Int
init{
this.name = name
this.age = age
}
}
演變2:直接在聲明類(lèi)的屬性的同時(shí)直接將構(gòu)造器的形參賦值給他們
class Person (name : String , age :Int){
private val name : String = name
private var age : Int = age
}
演變3:直接在主構(gòu)造器中定義類(lèi)的屬性
class Person (private val name : String ,private val age :Int){}
演變4:不包含其他操作函數(shù)
class Person (private val name : String ,private val age :Int)
4.2 次級(jí)構(gòu)造函數(shù)
構(gòu)造函數(shù)定義在類(lèi)體中
原型:
class MyButton : AppCompatButton {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, R.attr.buttonStyle)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
}
調(diào)用其他構(gòu)造器:次級(jí)構(gòu)造器:this.(參數(shù)列表)
同時(shí)定義了主構(gòu)造器和次級(jí)構(gòu)造器的情況下,次級(jí)構(gòu)造器必須直接或間接調(diào)用主構(gòu)造
class Person(name: String){
private var age : Int = 12
private val name : String = name
constructor(age : Int , name : String):this(name){
this.age = age
}
constructor(gender : Int , name : String ,age:Int):this(age,name){}
}
5. Kotlin的數(shù)據(jù)類(lèi),以及使用數(shù)據(jù)類(lèi)的注意事項(xiàng)?
數(shù)據(jù)類(lèi)
data class包含基本的數(shù)據(jù)類(lèi)型, 不包含任何功能函數(shù)。自動(dòng)生成操作數(shù)據(jù)類(lèi)型的基本方法。
數(shù)據(jù)類(lèi) 是只包含數(shù)據(jù)字段的類(lèi),類(lèi)似于vo , pojo , javabean .
數(shù)據(jù)類(lèi) 會(huì)自動(dòng)生成以下幾個(gè)方法:
equals()/hashCode()toString()componentN()copy()
使用 數(shù)據(jù)類(lèi) 的注意事項(xiàng):
- 主構(gòu)造函數(shù)必須至少包含一個(gè)參數(shù)
- 主構(gòu)造函數(shù)中所有的參數(shù)必須被標(biāo)記為
val/var - 數(shù)據(jù)類(lèi)不能包含以下修飾符:
abstract / inner / open / sealed
// 定義數(shù)據(jù)類(lèi)
data class BannerInfoBean(
var backgroundColor: String?=null,
var bannerHref: String?=null,
var bannerId: Int?=0,
var bannerImg: String?=null,
var bannerTitle: String?=null
)
// bannerInfoBean 的 get 和 set
GlideArmsUtil.getInstance()
.getBannersUrl(findView(R.id.banner_image),bannerInfoBean?.bannerImg)
bannerInfoBean?.bannerTitle = "輪播圖"

6. Kotlin中l(wèi)et,run,apply,also,with的區(qū)別
這幾個(gè)是Kotlin的作用域函數(shù),通過(guò)他們可以實(shí)現(xiàn)在對(duì)象的作用域中執(zhí)行代碼塊
我們實(shí)例化一個(gè)對(duì)象,用let生成一個(gè)臨時(shí)的作用域,在內(nèi)部直接用it訪問(wèn)該對(duì)象,比如上栗中,我們可以這樣設(shè)置:
bannerInfoBean?.let {
it.bannerImg = "dalkewr23e"
it.bannerTitle = "輪播圖"
}
作用域函數(shù)的兩個(gè)主要的區(qū)別:
- 引用上下文的方式
this : 作為lambda表達(dá)式的接受者(run apply with)
主要對(duì)對(duì)象成員進(jìn)行操作的lambda表達(dá)式用this,可省略this
it : 作為lambda表達(dá)式的參數(shù)(let also)
可以指定上下文對(duì)象的名稱(chēng)
調(diào)用上下文的成員時(shí)不能省略it
- 返回值
返回上下文對(duì)象:also apply
返回lambda表達(dá)式結(jié)果:let run with

7. 常見(jiàn)Java在Kotlin上的不同實(shí)現(xiàn)
- 使用類(lèi)名訪問(wèn)靜態(tài)變量的方法
- 靜態(tài)常量
- 擴(kuò)展方法
- 內(nèi)部類(lèi)
- 匿名內(nèi)部類(lèi):點(diǎn)擊事件
- 數(shù)據(jù)類(lèi)
- 智能類(lèi)型轉(zhuǎn)換
- 伴生對(duì)象
- 7.1 使用類(lèi)名訪問(wèn)靜態(tài)變量的方法
class Car{
companion object MyCar{
fun drive():Car = Car()
}
}
Java: 用static標(biāo)記,并用Car.drive()
Kotlin: 用companion 伴生對(duì)象標(biāo)記:companion object{}
有兩種調(diào)用方式:
Car.MyCar.drive()
Car.Companion.drive()
如果想做到跟Java一樣的調(diào)用方法:只需要在伴生對(duì)象中的變量加@JvmField,在函數(shù)上加@JvmStatic即可
- 7.2 靜態(tài)常量
Java:用static final標(biāo)記
Kotlin:用const關(guān)鍵字或者加注解@JvmField
- 7.3 擴(kuò)展方法
fun String?.toInt():Int{
return java.lang.Integer.parseInt(this)
}
- 7.4 內(nèi)部類(lèi)
沒(méi)有用innder標(biāo)記的內(nèi)部類(lèi)不能直接訪問(wèn)外部類(lèi)的成員
class A{
var a = 1
class B{
var b = 2
}
}
class A{
var a = 1
inner class B{
var b = a
}
}
- 7.5 匿名內(nèi)部類(lèi):點(diǎn)擊事件
Java:
btn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view){}
});
Kotlin:
btn.setOnClickListener(object : View.OnClickListener{
override fun onClick(v : View?){
print("122")
}
})
使用Kotlin的lambda:
btn.setOnClickListener{print("122")}
- 7.6 數(shù)據(jù)類(lèi)
Java沒(méi)有專(zhuān)門(mén)的數(shù)據(jù)類(lèi)型
Kotlin 有data關(guān)鍵字來(lái)生成自帶get/set/toString/hashCode等方法的數(shù)據(jù)類(lèi)
- 7.7 智能類(lèi)型轉(zhuǎn)換
父類(lèi)對(duì)象持有子類(lèi)引用
Java 用instanceOf判斷后還需要用強(qiáng)轉(zhuǎn)才能調(diào)用子類(lèi)方法
Kotlin 用is判斷后無(wú)需強(qiáng)轉(zhuǎn)可直接調(diào)用