Android開發(fā)者必然都用過單例模式吧。
在處理一些在應(yīng)用中只能存在一個(gè)實(shí)例的類的時(shí)候 我們時(shí)常會(huì)用單例模式。
通常單例
平時(shí)我們使用Java的時(shí)候,一個(gè)有效、安全的單例我們大概是這樣實(shí)現(xiàn)的:
//懶漢單例
public class Single {
private static Single ourInstance;
public static Single getInstance() {
if (null == ourInstance) {
createInstance();
}
return ourInstance;
}
private synchronized static void createInstance() {
if (ourInstance == null) {
ourInstance = new Single();
}
}
private Single() {
}
}
kotlin中有神奇的魔法,我們只需用object來修飾此類,kotlin會(huì)自動(dòng)為你實(shí)現(xiàn)一個(gè)安全的單例:
object Single
不禁感嘆一聲:如此簡(jiǎn)潔、優(yōu)雅
只需要考慮到對(duì)象不能有構(gòu)造函數(shù),因?yàn)槲覀儾徽{(diào)用任何構(gòu)造函數(shù)來訪問它們
而且只會(huì)在第一次被調(diào)用時(shí)生成實(shí)例
一個(gè)栗子:
/**
* 繼承BroadcastReceiver的一個(gè)單例
* Created by Song on 2017/9/1.
*/
object DemoSingle : BroadcastReceiver(){
//重寫父類方法
override fun onReceive(p0: Context?, p1: Intent?) {
}
//定義新方法
fun doSomeThing(p0 : String) {
Log.d("single", p0)
}
}
Application
Application 我們?cè)陂_發(fā)時(shí)也經(jīng)常將其作為一個(gè)單例來使用,但由于Android框架實(shí)例化類的方式。而我嘗試將它改寫為上面描述的單例的時(shí)候,程序啟動(dòng)時(shí)就會(huì)拋出異常。
因此我們不得不使用伴生對(duì)象companion object來實(shí)現(xiàn)這個(gè)偽單例
class MyKotlinApp : Application() {
companion object {
//標(biāo)準(zhǔn)委托,若在onCreate前調(diào)用此實(shí)例會(huì)直接拋出異常 IllegalStateException
// var instance: MyKotlinApp by Delegates.notNull()
//或者 這種方式不能處理基礎(chǔ)數(shù)據(jù)類型 int, float ,double等
lateinit var instance :MyKotlinApp
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
此處又出現(xiàn)了伴生對(duì)象、標(biāo)準(zhǔn)委托、懶加載等知識(shí)點(diǎn),且看稍后說明
伴生對(duì)象
其實(shí)大多嘗試過kotlin的coder都能在嘗試中看出來其作用,主要是代替靜態(tài)變量、靜態(tài)方法的一種寫法。
也確實(shí)如此,kotlin每個(gè)類都可以實(shí)現(xiàn)一個(gè)伴生對(duì)象,它是該類的所有實(shí)例共有的對(duì)象。它將類似于Java中的靜態(tài)字段。
懶加載
-
lateinit表示這個(gè)屬性開始是沒有值得,但是,在使用前將被賦值(否則,就會(huì)拋出異常)。
使用限制:lateinit不能用于修飾基礎(chǔ)類型(int、double等),且不能被賦值為null。 - 而
Delegates.notNull()使用了標(biāo)準(zhǔn)委托中的非空委托,表示在使用這個(gè)字段時(shí) 如果該字段值為null則拋出異常IllegalStateException
關(guān)于標(biāo)準(zhǔn)委托,下次再和大家一起詳細(xì)了解。
感謝您的閱讀,若覺得對(duì)你有用,或者有疑問,歡迎聯(lián)系我。