美文网首页
object 与 companion object的区别.md

object 与 companion object的区别.md

作者: zivxia | 来源:发表于2021-06-21 21:40 被阅读0次

object

首先来看一段object修饰的代码:

object TestObject {

    fun test(){


    }
}

接着看看这段代码对应的字节码

package com.lexin.gamebox.ui.mall.view;

import kotlin.Metadata;

@Metadata(
   mv = {1, 1, 16},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\bÆ\u0002\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004¨\u0006\u0005"},
   d2 = {"Lcom/lexin/gamebox/ui/mall/view/TestObject;", "", "()V", "test", "", "app_debug"}
)
public final class TestObject {
   public static final TestObject INSTANCE;

   public final void test() {
   }

   private TestObject() {
   }

   static {
      TestObject var0 = new TestObject();
      INSTANCE = var0;
   }
}

可以看到这是一个饿汉式的单例,一开始就创建了对象。object可以单独创建,作用域为整个类,里面的成员和方法,可以直接通过object类来调用。由此我们再来看一下object的其他用法:

对象表达式

继承一个匿名对象

val textView = findViewById<TextView>(R.id.tv)
textView.setOnClickListener(object : OnClickListener {
        override fun onClick(p0: View?) {
            Toast.makeText(this@TestActivity, "点击事件生效", Toast.LENGTH_LONG)
        }
 
})
对象声明

用object 修饰的类为静态类,里面的方法和变量都为静态的。

直接声明类

直接声明类

object DemoManager {
    private val TAG = "DemoManager"
        
    fun a() {
        Log.e(TAG,"此时 object 表示 声明静态内部类")
    }
    
}
声明静态内部类

类内部的对象声明,没有被inner 修饰的内部类都是静态的

class DemoManager{
    object MyObject {
        fun a() {
            Log.e(TAG,"此时 object 表示 直接声明类")
        }
    }
}

companion object

同样,先来看下源码:

class Test {

 var field: String = "haha";

    companion object A{

        fun testCompanionObject(){

        }

    }

再来看看转成字节码后的样子:

package com.lexin.gamebox.ui.mall.view;

import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 1, 16},
   bv = {1, 0, 3},
   k = 1,
   d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},
   d2 = {"Lcom/lexin/gamebox/ui/mall/view/Test;", "", "()V", "A", "app_debug"}
)
public final class Test {
   @NotNull
   private static String field = "haha";
   public static final Test.A A = new Test.A((DefaultConstructorMarker)null);

   @Metadata(
      mv = {1, 1, 16},
      bv = {1, 0, 3},
      k = 1,
      d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0005\n\u0002\u0010\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\t\u001a\u00020\nR\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\"\u0004\b\u0007\u0010\b¨\u0006\u000b"},
      d2 = {"Lcom/lexin/gamebox/ui/mall/view/Test$A;", "", "()V", "field", "", "getField", "()Ljava/lang/String;", "setField", "(Ljava/lang/String;)V", "testCompanionObject", "", "app_debug"}
   )
   public static final class A {
      @NotNull
      public final String getField() {
         return Test.field;
      }

      public final void setField(@NotNull String var1) {
         Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
         Test.field = var1;
      }

      public final void testCompanionObject() {
      }

      private A() {
      }

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

可以看到A变成静态的类,A中的成员变量filed和成员方法testCompanionObject都变成了final static。companion object只能定义在class中,并且一个class中只能定一个一个companion object。companion object作用域为代码块,里面成员和方法可通过companion object直接调用(companion object会生成一个companion对象)

JvmStatic

JvmStatic 定义静态方法,只能在object或者companion object里使用

相关文章

网友评论

      本文标题:object 与 companion object的区别.md

      本文链接:https://www.haomeiwen.com/subject/dqjuyltx.html