当前位置: 首页 > news >正文

kotlin init执行顺序

一 代码

kotlin:



package test.f

class Test1 {
}

class TestInit(s: String, i: Int) {

    var name: String? = null
    var age = 0

    private var a :Int = 1

    init {
        this.name = s
        this.age = i
        println("init代码块: $name, $age")
    }

}




转成java

// Test1.java
package test.f;

import kotlin.Metadata;

@Metadata(
   mv = {2, 0, 0},
   k = 1,
   xi = 48,
   d1 = {"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0003"},
   d2 = {"Ltest/f/Test1;", "", "()V", "untitled"}
)
public final class Test1 {
}
// TestInit.java
package test.f;

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

@Metadata(
   mv = {2, 0, 0},
   k = 1,
   xi = 48,
   d1 = {"\u0000\u0018\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0002\b\r\u0018\u00002\u00020\u0001B\u0015\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005¢\u0006\u0002\u0010\u0006R\u000e\u0010\u0007\u001a\u00020\u0005X\u0082\u000e¢\u0006\u0002\n\u0000R\u001a\u0010\b\u001a\u00020\u0005X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\t\u0010\n\"\u0004\b\u000b\u0010\fR\u001c\u0010\r\u001a\u0004\u0018\u00010\u0003X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u000e\u0010\u000f\"\u0004\b\u0010\u0010\u0011¨\u0006\u0012"},
   d2 = {"Ltest/f/TestInit;", "", "s", "", "i", "", "(Ljava/lang/String;I)V", "a", "age", "getAge", "()I", "setAge", "(I)V", "name", "getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "untitled"}
)
public final class TestInit {
   @Nullable
   private String name;
   private int age;
   private int a;

   public TestInit(@NotNull String s, int i) {
      Intrinsics.checkNotNullParameter(s, "s");
      super();
      this.a = 1;
      this.name = s;
      this.age = i;
      String var3 = "init代码块: " + this.name + ", " + this.age;
      System.out.println(var3);
   }

   @Nullable
   public final String getName() {
      return this.name;
   }

   public final void setName(@Nullable String var1) {
      this.name = var1;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }
}

二 解释说明

在Kotlin中,类的初始化顺序严格按照代码中声明的顺序执行。对于提供的TestInit类,执行顺序如下:

  1. 主构造函数参数处理:首先接收s: Stringi: Int
  2. 属性初始化:按声明顺序依次初始化:
    name: String? = null
    age: Int = 0
    private var a: Int = 1
  3. 执行init:最后运行init中的代码,设置nameage的值,并打印信息。

为什么init块在a之后执行?
因为a的声明和初始化(private var a: Int = 1)出现在init块之前。Kotlin会先处理所有在init块之前声明的属性,再执行init块。这保证了在init块中访问a时,它已经被正确初始化。

关键点
声明顺序决定初始化顺序:属性和init块的执行顺序完全由它们在类体中的位置决定。
init块属于初始化阶段:所有在init块之前的属性会先初始化,确保init块中的逻辑可以依赖这些已初始化的值。

三 总结

根据Kotlin的文档,当创建一个类的实例时,初始化顺序是这样的:
首先,主构造函数中的参数被处理;
接着,类体中声明的属性按照它们在代码中的顺序进行初始化;
然后,init块按照它们在类体中的出现顺序执行。
如果有多个init块,它们会按照顺序依次执行。
最后,次构造函数中的代码执行。

相关文章:

  • 制作PaddleOCR/PaddleHub的Docker镜像
  • 解决 IntelliJ IDEA 方法断点导致程序无法运行的问题
  • 气象可视化卫星云图的方式:方法与架构详解
  • Python----计算机视觉处理(Opencv:霍夫变换)
  • Mysql中各种连接的区别
  • 父子组件传递数据和状态管理数据
  • PaddleHub-GPU镜像制作
  • 2025.03.23【前沿工具】| CellPhoneDB:基因网络分析与可视化的利器
  • 面试题分享-多线程顺序打印奇偶数
  • SpringBoot2集成Elasticsearch8(使用spring-boot-starter-data-elasticsearch)
  • Oracle 外键/引用完整性(Foreign Key / Referential Integrity Constraints)
  • DolphinScheduler中shell安装脚本说明
  • 解线性方程组的直接方法:高斯消元法与其程序实现
  • 如何通过 iTick 外汇数据 API 与 Cursor AI 实现量化策略开发
  • 设计模式的六大原则
  • PHP回调后门分析
  • 比R版本快几十倍| Pyscenic单细胞转录因子预测
  • 项目日记 -云备份 -服务端配置信息模块
  • 深入解析 Python 正则表达式:全面指南与实战示例
  • Python实现小红书app版爬虫
  • 习近平在上海考察
  • 商务部:一季度我国服务贸易较快增长,进出口总额同比增8.7%
  • 三位成功女性,如何应对失败
  • 梅花画与咏梅诗
  • 新城市志|中国消费第一城,迎来“补贴力度最大”购物节
  • 李彦宏:DeepSeek不是万能,多模态将是未来基础模型的标配