日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Kotlin object的用法和內(nèi)存泄漏研究

作者:jzlhll123 更新時間: 2022-08-30 編程語言

通過java中互相調(diào)用和編譯后的字節(jié)碼或反編譯來分析。本質(zhì)上是能夠相互轉(zhuǎn)換代碼的。

1. 對象申明:修飾class名

object className {} 的類名申明方式。

object ObjectClass {
    var a = 0
    fun foo(){}
}

//反編譯得到如下
/* loaded from: ObjectClass.class */
public final class ObjectClass {
    public static final ObjectClass INSTANCE = new ObjectClass();
    private static int a;

    private ObjectClass() {
    }

    public final int getA() {
        return a;
    }

    public final void setA(int i) {
        a = i;
    }

    public final void foo() {
    }
}

因此,object class就是java中,final的class配上private構(gòu)造函數(shù),加惡漢單例INSTANCE
如果我們要在java中調(diào)用,還得通過MyCalss.INSTANCE.a()來調(diào)用。
備注:想讓a()函數(shù)變成static,則通過注解@JVMStatic注解來實現(xiàn),對象變量通過@JVMField

object ObjectClass {
    @JvmField
    var a = 0

    @JvmStatic
    fun foo(){}
}
//反編譯成如下:
public final class ObjectClass {
    @NotNull
    public static final ObjectClass INSTANCE = new ObjectClass();
    @JvmField
    public static int a;

    private ObjectClass() {
    }

    @JvmStatic
    public static final void foo() {
    }
}

2. 伴生對象:companion object

class MyClass {
   companion object {
       val aa = 1
       fun a(){}
   }
}

//反編譯為java代碼如下:
public final class MyClass {
   private static final int aa = 1;
   public static final Companion Companion = new Companion((DefaultConstructorMarker)null);
    
   public static final class Companion {
      public final int getAa() {
         return MyClass.aa;
      }

      public final void a() {
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

在Kotlin中調(diào)用MyClass.a(), 在Java中調(diào)用 MyClass.Companion.a();
理解第一章的object class后,再理解伴生對象事半功倍。變量是放在主類中的static變量。而函數(shù)則是伴生類(靜態(tài)內(nèi)部類)中的函數(shù)。同樣的,覺得這種調(diào)用不爽,可以通過注解@JVMStatic或者@JVMField處理。

3. 對象表達式

3.1 基本用法
Thread(object :Runnable{
    override fun run() {
        println("hah")
    }
}).start()

Collections.sort(list, object : Comparator<String?> {
    override fun compare(o1: String?, o2: String?): Int {
        if (o1 == null) {
            return -1;
        }
        if (o2 == null) {
            return 1;
        }
        return o1.compareTo(o2)
    }
})
//lambda寫法
Collections.sort(list, { o1: String, o2: String ->
        if (o1 == null) {
            return@sort -1;
        }
        if (o2 == null) {
            return@sort 1;
        }
        return@sort o1.compareTo(o2)
})

匿名內(nèi)部類,也會有IDEA提示,建議改成lambda(備注2點,第一點,有的可以提示,有的不提示。第二點,與java不同,java里面箭頭后面用花括號包住即可,而kotlin不能添加{})。kotlin的lambda省略寫法很多,這里不做介紹,按照idea提示自行轉(zhuǎn)換吧。

3.2 更強大的用法

多個繼承使用,達到了超越j(luò)ava的匿名內(nèi)部類的能力。

 val superMan = object: Man("Clark"), Flyable, SuperHearing, SuperVision {
        override fun hearSubtleNoises() {
        }
        override fun seeThroughWalls() {
        }
        override fun fly() {
        }
    }
3.3 對象表達式-直用-函數(shù)
    //Object a = clas.publicFoo();
    //外部只能獲取到一個object。沒有任何用處。
    //推薦如下加上private。
    fun publicFoo() = object {
        val x: String = "y"
        fun getValue() = 6
    }

    //私有object表達式
    private fun foo() = object {
        val x: String = "y"
        fun getValue() = 6
    }
    //測試上面的代碼
    fun test() {
        val f = foo()
        val xx = f.x
        f.getValue()
    }
1.5 對象表達式-直用-變量
//無法被引用內(nèi)部參數(shù),是個any
val publicValue = object  {
    val x: String = "y"
    fun getValue() = 6
}
//可以被引用
private val privateValue = object {
    val x = "aaa"
    fun getValue() = 7
}

private fun test() {
    privateValue.x
    val v = privateValue.getValue()
}

內(nèi)存泄漏研究

請?zhí)砑訄D片描述
kotlin唯一的好處是,對于沒有引用外部類實例的情況下,在對象表達式上有所優(yōu)化。

kotlin分為:
靜態(tài)內(nèi)部類,內(nèi)部類,匿名內(nèi)部類,lambda表達式。

第一種:java內(nèi)部不用static修飾,持有外部引用,對應(yīng)kotlin 添加inner標記;
第二種:java內(nèi)部使用static修飾,不持有外部引用,對應(yīng)直接申明class的kotlin內(nèi)部類;

public class Test {
    int x = 1;
    //《1. 內(nèi)部類》:會持有外部引用。
    class Inner{
        void a() {
            x = x + 1;
        }
    }
    //《2. 靜態(tài)內(nèi)部類》不持有外部引用
    static class Inner{
        void a() {
            x = x + 1;
        }
    }
    
     void foo() {
        //new Runnable屬于《3. 匿名內(nèi)部類》
        new Thread(new Runnable() {
            @Override
            public void run() {

            }
        }).start();
    }
    
    void foo() {
        //《4. lambda》
        new Thread(() -> {
        
        }).start();
    }
class MyClass {
    var aaa = "a"
    //持有外部引用。
    inner class NestClass {
        fun a(): String {
            return aaa
        }
    }
    //不持有外部引用,相當(dāng)于static final class
	class NestClass {
        fun a(): String {
            return aaa
        }
    }
}

原文鏈接:https://blog.csdn.net/jzlhll123/article/details/126593235

欄目分類
最近更新