最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Kotlin?object的幾種用法示例詳解

 更新時(shí)間:2022年12月08日 11:03:03   作者:無(wú)糖可樂(lè)愛(ài)好者  
這篇文章主要為大家介紹了Kotlin?object的幾種用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1.object:匿名內(nèi)部類

在Android最常用的匿名內(nèi)部類之一就是點(diǎn)擊事件,用Java語(yǔ)言寫(xiě)的話就是下面這樣:

public interface OnClickListener {
    void onClick(View v);
}
button.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
    }
});

上面的代碼在Kotlin中就要這么寫(xiě)

interface OnClickListener {
    fun onClick(v: View)
}
button.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View) {
    }
})

上面的代碼中object: View.OnClickListener就是匿名內(nèi)部類的使用方式。

這里的代碼為了說(shuō)明【object: 匿名內(nèi)部類】的用法所以寫(xiě)的比較啰嗦,如果用Lambda寫(xiě)法的話可以這么寫(xiě)

button.setOnClickListener {
}

上面是匿名內(nèi)部類常用的一種方式,還有另一種用法就是:在繼承一個(gè)抽象類的同時(shí)還可以實(shí)現(xiàn)多個(gè)接口,直接看代碼:

interface Behavior {
    fun sleep()
}
interface Characteristics {
    fun gender()
}
abstract class Person {
    abstract fun walk()
}
fun main() {
    // 這個(gè)匿名內(nèi)部類,在繼承了Person類的同時(shí),還實(shí)現(xiàn)了Behavior(行為)、Characteristics(特征)兩個(gè)接口
    val item = object : Person(), Behavior, Characteristics {
        override fun sleep() {
        }
        override fun gender() {
        }
        override fun walk() {
        }
    }
}

對(duì)上面的代碼說(shuō)明:在繼承了Person類的同時(shí),還實(shí)現(xiàn)了Behavior(行為)、Characteristics(特征)兩個(gè)接口并分別重寫(xiě)了他們的方法,這種用法靈活性比較高。

2.object: 伴生對(duì)象

Kotlin 當(dāng)中沒(méi)有 static 關(guān)鍵字,所以我們沒(méi)有辦法直接定義靜態(tài)方法和靜態(tài)變量。不過(guò),Kotlin 還是為我們提供了伴生對(duì)象,來(lái)幫助實(shí)現(xiàn)靜態(tài)方法和變量。

先看一種嵌套類的特殊情況

class Person {
    object InnerSingleton {
        fun foo() {}
    }
}
//反編譯后的Java代碼
public final class Person {
    public static final class InnerSingleton {
        @NotNull
        public static final Person.InnerSingleton INSTANCE;
        public final void foo() {
        }
        private InnerSingleton() {
        }
        static {
            Person.InnerSingleton var0 = new Person.InnerSingleton();
            INSTANCE = var0;
        }
    }
}

由以上代碼可知定義的foo方法并不是一個(gè)靜態(tài)方法,那要如何實(shí)現(xiàn)這個(gè)靜態(tài)方法呢,可以foo方法上面加入注解@JvmStatic,這樣反編譯后foo方法就是一個(gè)靜態(tài)方法了

class Person {
    object InnerSingleton {
        @JvmStatic
        fun foo() {}
    }
}
//反編譯后的Java代碼
public final class Person {
    public static final class InnerSingleton {
        @NotNull
        public static final Person.InnerSingleton INSTANCE;
        @JvmStatic
        public static final void foo() {
        }
        private InnerSingleton() {
        }
        static {
            Person.InnerSingleton var0 = new Person.InnerSingleton();
            INSTANCE = var0;
        }
    }
}

經(jīng)過(guò)這么改動(dòng)Kotlin和Java的實(shí)現(xiàn)方式就都可以這么寫(xiě)

Person.InnerSingleton.foo()

此時(shí)還有一個(gè)問(wèn)題,foo方法的InnerSingleton有點(diǎn)多余,它并沒(méi)有實(shí)際意義,想直接調(diào)用Person.foo()要怎么做?

object前面加入一個(gè)companion關(guān)鍵字即可

//Kotlin代碼
class Person {
    companion object InnerSingleton {
        @JvmStatic
        fun foo() {
        }
    }
}
//反編譯后的代碼
public final class Person {
    @NotNull
    public static final Person.InnerSingleton InnerSingleton = new Person.InnerSingleton((DefaultConstructorMarker)null);
    @JvmStatic
    public static final void foo() {
        InnerSingleton.foo();
    }
    public static final class InnerSingleton {
        @JvmStatic
        public final void foo() {
        }
        private InnerSingleton() {
        }
        // $FF: synthetic method
        public InnerSingleton(DefaultConstructorMarker $constructor_marker) {
            this();
        }
    }
}

加入companion就實(shí)現(xiàn)了Person.foo()的調(diào)用。companion object就是Kotlin中的伴生對(duì)象, 它其實(shí)是嵌套單例的一種也是情況。

通過(guò)上面的代碼可以得出一個(gè)結(jié)論:當(dāng)伴生對(duì)象存在時(shí)如果還存在

@JvmStatic修飾的方法或者屬性,那么Kotlin編譯成Java代碼后它就會(huì)被挪到外部的類中變成靜態(tài)成員。嵌套單例是

object單例的一種特殊情況,伴身對(duì)象是嵌套單例的一種特殊情況。

3.單例模式

Kotlin中定義一個(gè)普通的單例模式非常簡(jiǎn)單只需要在類名前面用object聲明即可

object Utils{
}

這樣就能實(shí)現(xiàn)單例,但是Java中的單例是比較復(fù)雜的,并且還有懶漢式和餓漢式之分,這樣真的就能定義嗎?

我們看一下這段代碼反編譯成Java的代碼看一看就很清楚了:

public final class Utils {
    @NotNull
    public static final Utils INSTANCE;
    private Utils() {
    }
    static {
        Utils var0 = new Utils();
        INSTANCE = var0;
    }
}

static中的代碼由虛擬機(jī)決定只會(huì)運(yùn)行一次,同時(shí)在保證線程安全的前提下也保證了INSTANCE只運(yùn)行一次。

但是這里有2個(gè)缺陷:

  • 不支持懶加載
  • 不能傳遞參數(shù),在Android中會(huì)經(jīng)常用到context的情況,不能傳參這個(gè)用法就沒(méi)有意義

那要如何解決?

  • 單例模式——借助懶加載委托
class Person(val name: String) {
}
fun main() {
    val user by lazy { Person("張三") }
    println("user is name ${user.name}")
}

上面的代碼使用了by lazy{ }創(chuàng)建了Person對(duì)象,而Person對(duì)象最終創(chuàng)建的時(shí)機(jī)是在println創(chuàng)建的,也就是說(shuō)懶加載委托的特點(diǎn)就是只有在使用這個(gè)對(duì)象是才會(huì)創(chuàng)建實(shí)例。

  • 單例模式—— 伴生對(duì)象 Double Check

直接看代碼,代碼是從《朱凱·Kotlin編程第一課》直接拷貝過(guò)來(lái)的

class UserManager private constructor(name: String) {
    companion object {
        @Volatile
        private var INSTANCE: UserManager? = null
        fun getInstance(name: String): UserManager =
        // 第一次判空
        INSTANCE ?: synchronized(this) {
            // 第二次判空
            INSTANCE ?: UserManager(name).also { INSTANCE = it }
        }
    }
}
fun main() {
    // 使用
    UserManager.getInstance("Tom")
}

這里首先定義了一個(gè)INSTANCE并且用private修飾這樣就可以保證不能被外界直接訪問(wèn),同時(shí)添加了@Volatile注解可以保證INSTANCE的可見(jiàn)性,而 getInstance() 方法當(dāng)中的 synchronized,保證了 INSTANCE 的原子性。因此,這種方案還是線程安全的。

另外還要注意的一點(diǎn)是初始化定義的INSTANCE的默認(rèn)值時(shí)null你這也就保證了只有在使用它的時(shí)候才會(huì)被實(shí)例化,也就是說(shuō)實(shí)現(xiàn)懶加載的模式。

這中實(shí)現(xiàn)方式也是可以傳參的,在getInstance()方法中定義需要的屬性即可實(shí)現(xiàn)傳參

這個(gè)代碼其實(shí)跟Java的懶漢模式 + synchronized 同步鎖非常相似

public class UserManager {
    private static volatile UserManager mInstance = null;
    private UserManager() {
    }
    public static UserManager getInstance() {
        if (mInstance == null) {
            synchronized (UserManager.class) {
                if (mInstance == null) {
                    mInstance = new UserManager();
                }
            }
        }
        return mInstance;
    }
}

上面介紹了3中單例模式的實(shí)現(xiàn)方式,他們的使用場(chǎng)景如下:

  • 如果單例占用內(nèi)存很小并且堆內(nèi)存不敏感也不需要傳參,直接使用object即可,例如常用且無(wú)需傳參的的Utils類;
  • 如果單例占用內(nèi)存很小并且不需要傳參,但是它的內(nèi)部屬性會(huì)觸發(fā)消耗資源的網(wǎng)絡(luò)請(qǐng)求和數(shù)據(jù)庫(kù)查詢,這是就需要用object搭配by lazy{ };
  • 如果工程比較簡(jiǎn)單,只有少數(shù)的單例場(chǎng)景、懶加載需求、需要傳遞參數(shù)就需要使用Double Check的方式了,例如PreferenceUtils。

以上就是Kotlin object的幾種用法示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Kotlin object用法示例的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 實(shí)例講解Android中的AIDL內(nèi)部進(jìn)程通信接口使用

    實(shí)例講解Android中的AIDL內(nèi)部進(jìn)程通信接口使用

    這篇文章主要通過(guò)實(shí)例介紹了Android中的AIDL內(nèi)部進(jìn)程通信接口使用,文中通過(guò)一個(gè)音樂(lè)播放的服務(wù)編寫(xiě)例子來(lái)講解AIDL的傳遞對(duì)象及一般使用步驟,需要的朋友可以參考下
    2016-04-04
  • Android編程自定義Notification實(shí)例分析

    Android編程自定義Notification實(shí)例分析

    這篇文章主要介紹了Android編程自定義Notification的用法,結(jié)合實(shí)例形式簡(jiǎn)單分析了自定義Notification的具體功能與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-12-12
  • Android仿字節(jié)顏色自定義進(jìn)度條

    Android仿字節(jié)顏色自定義進(jìn)度條

    這篇文章主要為大家詳細(xì)介紹了Android仿字節(jié)顏色自定義進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Android應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁(yè)面的方法

    Android應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁(yè)面的方法

    最近在工作中遇到一個(gè)需求,推廣部門要求實(shí)現(xiàn)應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁(yè)面,通過(guò)查找一些資料,實(shí)現(xiàn)出來(lái)了,覺(jué)得有必要整理下方便以后或者有需要的朋友們參考借鑒,下面來(lái)一起詳細(xì)看看Android應(yīng)用自動(dòng)跳轉(zhuǎn)到應(yīng)用市場(chǎng)詳情頁(yè)面的方法吧。
    2016-12-12
  • Android按鈕單擊事件的四種常用寫(xiě)法總結(jié)

    Android按鈕單擊事件的四種常用寫(xiě)法總結(jié)

    這篇文章主要介紹了Android按鈕單擊事件的四種常用寫(xiě)法總結(jié),比較了常見(jiàn)的四種寫(xiě)法的優(yōu)劣,有不錯(cuò)的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • ViewPager實(shí)現(xiàn)圖片切換效果

    ViewPager實(shí)現(xiàn)圖片切換效果

    這篇文章主要為大家詳細(xì)介紹了ViewPager實(shí)現(xiàn)圖片切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • Android編程設(shè)計(jì)模式之模板方法模式詳解

    Android編程設(shè)計(jì)模式之模板方法模式詳解

    這篇文章主要介紹了Android編程設(shè)計(jì)模式之模板方法模式,結(jié)合實(shí)例形式詳細(xì)分析了Android模板方法模式的概念、功能、使用場(chǎng)景、用法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下
    2017-12-12
  • Android實(shí)現(xiàn)應(yīng)用內(nèi)置語(yǔ)言切換功能

    Android實(shí)現(xiàn)應(yīng)用內(nèi)置語(yǔ)言切換功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)應(yīng)用內(nèi)置語(yǔ)言切換功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • android如何默認(rèn)打開(kāi)小區(qū)廣播具體實(shí)現(xiàn)

    android如何默認(rèn)打開(kāi)小區(qū)廣播具體實(shí)現(xiàn)

    小區(qū)廣播的開(kāi)關(guān),1是打開(kāi),0是關(guān)閉;0x00就默認(rèn)關(guān)閉,改成0x01就是默認(rèn)打開(kāi),具體修改如下,感興趣的朋友可以參考下哈
    2013-06-06
  • Android實(shí)現(xiàn)拼多多地址選擇器

    Android實(shí)現(xiàn)拼多多地址選擇器

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)拼多多地址選擇器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05

最新評(píng)論

鄂托克前旗| 宿州市| 大荔县| 桦甸市| 辽宁省| 昭平县| 乳山市| 卢湾区| 红安县| 富平县| 尼勒克县| 凤阳县| 申扎县| 延边| 河东区| 盐城市| 北安市| 当涂县| 建昌县| 平泉县| 博乐市| 阿合奇县| 江都市| 通化市| 安新县| 娱乐| 和田县| 玛多县| 江油市| 石渠县| 上犹县| 阿拉善左旗| 延吉市| 乌拉特中旗| 红原县| 滕州市| 金湖县| 泾阳县| 广丰县| 保德县| 山丹县|