kotlin中 init、constructor、companion object 调用顺序

package com.androidtv.pos

/**
 * @author wuqiqi
 * date on 2020/8/19
 * describe 测试
 */
class Apple {

    private var speak: String = "小啊小苹果"

    /* 主构造方法*/
    constructor(){
        println("主构造方法constructor()调用")
    }

    /* 次构造方法*/
    constructor(name:String, age:Int):this(){
        println("次带参数构造方法constructor(name:$name, age:$age)")
    }

    init {
        println("Apple init")
    }

    init {
        println("Apple init:name:${speak}")
    }

    /*伴生对象*/
    companion object {
        val instance: Apple by lazy {
            Apple("wqq", 100)
        }

        /*伴生对象中的初始化代码*/
        init {
            println("companion init 1")
        }

        init {
            println("companion init 2")
        }
    }
}

 调用App() ,出现结果:

exclude patterns:
companion init 1
companion init 2
Apple init
Apple init:name:小啊小苹果
主构造方法constructor()调用

调用有参构造方法,出现结果

exclude patterns:
companion init 1
companion init 2
Apple init
Apple init:name:小啊小苹果
主构造方法constructor()调用
次带参数构造方法constructor(name:heihei, age:28)

可以看看 kotlin转java的代码:

package com.androidtv.pos;

import kotlin.Lazy;
import kotlin.LazyKt;
import kotlin.Metadata;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = {1, 1, 18},
   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\u0000\n\u0002\u0010\b\n\u0002\b\u0004\u0018\u0000 \t2\u00020\u0001:\u0001\tB\u0007\b\u0016¢\u0006\u0002\u0010\u0002B\u0017\b\u0016\u0012\u0006\u0010\u0003\u001a\u00020\u0004\u0012\u0006\u0010\u0005\u001a\u00020\u0006¢\u0006\u0002\u0010\u0007R\u000e\u0010\b\u001a\u00020\u0004X\u0082\u000e¢\u0006\u0002\n\u0000¨\u0006\n"},
   d2 = {"Lcom/androidtv/pos/Apple;", "", "()V", "name", "", "age", "", "(Ljava/lang/String;I)V", "speak", "Companion", "app"}
)
public final class Apple {
   private String speak;
   @NotNull
   private static final Lazy instance$delegate;
   public static final Apple.Companion Companion = new Apple.Companion((DefaultConstructorMarker)null);

   public Apple() {
      this.speak = "小啊小苹果";
      String var1 = "Apple init";
      boolean var2 = false;
      System.out.println(var1);
      var1 = "Apple init:name:" + this.speak;
      var2 = false;
      System.out.println(var1);
      var1 = "主构造方法constructor()调用";
      var2 = false;
      System.out.println(var1);
   }

   public Apple(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      this();
      String var3 = "次带参数构造方法constructor(name:" + name + ", age:" + age + ')';
      boolean var4 = false;
      System.out.println(var3);
   }

   static {
      instance$delegate = LazyKt.lazy((Function0)null.INSTANCE);
      String var0 = "companion init 1";
      boolean var1 = false;
      System.out.println(var0);
      var0 = "companion init 2";
      var1 = false;
      System.out.println(var0);
   }

   @Metadata(
      mv = {1, 1, 18},
      bv = {1, 0, 3},
      k = 1,
      d1 = {"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0002\b\u0005\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002R\u001b\u0010\u0003\u001a\u00020\u00048FX\u0086\u0084\u0002¢\u0006\f\n\u0004\b\u0007\u0010\b\u001a\u0004\b\u0005\u0010\u0006¨\u0006\t"},
      d2 = {"Lcom/androidtv/pos/Apple$Companion;", "", "()V", "instance", "Lcom/androidtv/pos/Apple;", "getInstance", "()Lcom/androidtv/pos/Apple;", "instance$delegate", "Lkotlin/Lazy;", "app"}
   )
   public static final class Companion {
      @NotNull
      public final Apple getInstance() {
         Lazy var1 = Apple.instance$delegate;
         Apple.Companion var2 = Apple.Companion;
         Object var3 = null;
         boolean var4 = false;
         return (Apple)var1.getValue();
      }

      private Companion() {
      }

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

总结:由于伴生对象中的代码是在类加载时就会执行,所以伴生类初始化会先执行,再执行本身构造方法, 会把init代码 合并到构造方法中,但会插到构造方法最前面。

你可能感兴趣的:(#,kotlin)