
kotlin之object關(guān)鍵字.png
object關(guān)鍵字主要有三種使用場(chǎng)景
- 對(duì)象聲明(object declaration)
- 伴生對(duì)象(companion object)
- 對(duì)象表達(dá)式(object expression)
對(duì)象聲明(object declaration)
- 將類的聲明和定義該類的單例對(duì)象結(jié)合在一起(即通過object就實(shí)現(xiàn)了單例模式)
- 對(duì)象聲明中不能包含構(gòu)造器(包括主構(gòu)造器和次級(jí)構(gòu)造器)
對(duì)象聲明實(shí)例解析以及在kotlin和java代碼中的調(diào)用
object UserManager {
fun saveUser()
}
// 反編譯出的Java代碼
public final class UserManager {
public static final UserManager INSTANCE;
public final void saveUser() {
}
private UserManager() {
}
static {
UserManager var0 = new UserManager();
INSTANCE = var0;
}
}
在kotlin和java代碼中,它們的調(diào)用方式有點(diǎn)差別:
- kotlin代碼調(diào)用:
UserManager.saveUser()- java代碼調(diào)用:
UserManager.INSTANCE.saveUser();
伴生對(duì)象(companion object)
kotlin中為什么會(huì)出現(xiàn)伴生對(duì)象?
因?yàn)樵趉otlin中是沒有static關(guān)鍵字的,也就意味著沒有靜態(tài)方法和靜態(tài)成員。那么在kotlin中如果想要表達(dá)這種概念,可以使用包級(jí)別函數(shù)(package-level funcation)和伴生對(duì)象(companion object)。
伴生對(duì)象語法形式
class ClassName {
// 伴生對(duì)象名可以省略,默認(rèn)為Companion
companion object 伴生對(duì)象名 {
// define field and method
}
}
伴生對(duì)象實(shí)例解析以及在kotlin和java代碼中的調(diào)用
class App {
companion object {
fun getAppContext() {}
}
}
// 反編譯出的Java代碼
public final class App {
public static final App.Companion Companion = new App.Companion((DefaultConstructorMarker)null);
public static final class Companion {
public final void getAppContext() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
與對(duì)象聲明類似,它們?cè)趉otlin和java代碼中的調(diào)用方式也有點(diǎn)差別:
- kotlin代碼調(diào)用:
App.getAppContext()- java代碼調(diào)用:
App.Companion.getAppContext();
對(duì)象表達(dá)式(object expression)
對(duì)象表達(dá)式常用來作為匿名內(nèi)部類的實(shí)現(xiàn)
private val callBack = object : CallBack {
override fun onSuccess() {}
override fun onFailure() {}
}
// 通過對(duì)象表達(dá)式實(shí)現(xiàn)點(diǎn)擊事件回調(diào)
btn.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
TODO("Not yet implemented")
}
})
擴(kuò)展
有這樣一個(gè)疑問,在對(duì)象聲明和伴生對(duì)象中,java代碼調(diào)用總會(huì)跟上
INSTANCE或者Companion,直觀上感覺不太友好,能不能像kotlin代碼那樣可以直接調(diào)用?
答案肯定是可以的。需要使用kotlin自帶的注解:@JvmStatic或者@JvmField,這樣就可以和kotlin調(diào)用保持一致。
@JvmStatic既可以修飾屬性,也可以修飾方法;而@JvmField只能修飾屬性
對(duì)于對(duì)象聲明
object UserManager {
@JvmStatic
fun saveUser()
}
// 反編譯出的Java代碼
public final class UserManager {
public static final UserManager INSTANCE;
// 和之前差別在于,這里是靜態(tài)方法,在java代碼中可以直接調(diào)用
@JvmStatic
public static final void saveUser() {
}
private UserManager() {
}
static {
UserManager var0 = new UserManager();
INSTANCE = var0;
}
}
// java調(diào)用
UserManager.saveUser();
對(duì)于伴生對(duì)象
class App {
companion object{
@JvmStatic
fun getAppContext() {}
}
}
// 反編譯出的Java代碼
public final class App {
public static final App.Companion Companion = new App.Companion((DefaultConstructorMarker)null);
// 和之前差別在于,這里多出了一個(gè)靜態(tài)方法,它調(diào)用的是Companion內(nèi)的getAppContext()
// 這樣我們可以不用調(diào)用Companion.getAppContext(),而可以直接調(diào)用該方法
@JvmStatic
public static final void getAppContext() {
Companion.getAppContext();
}
public static final class Companion {
@JvmStatic
public final void getAppContext() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
// java調(diào)用
App.getAppContext();