Kotlin:object關(guān)鍵字總結(jié)

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();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容