Kotlin在声明之前初始化变量?

时间:2018-01-11 07:38:08

标签: constructor initialization kotlin declaration

这是我的测试代码:

class Test {
    init {
        a = 1
    }

    constructor() {
        a = 2
    }

    private var a: Int

    init {
        a = 3
    }
}

如果我删除了辅助构造函数:

class Test {
    init {
        a = 1 // Error: Variable cannot be initialized before declaration
    }

//    constructor() {
//        a = 2
//    }

    private var a: Int

    init {
        a = 3
    }
}

我知道

  

在实例初始化期间,初始化程序块的执行顺序与它们在类主体中的显示顺序相同。

但是,如果存在辅助构造函数,为什么我可以在声明之前初始化变量?

更新

我发现了一件有趣的事情:

class Test {
    init {
        a = log(1)
    }

    constructor() {
        a = log(2)
    }

    private var a: Int = log(0)

    init {
        a = log(3)
    }
}

fun log(i: Int): Int {
    println(i)
    return i
}

fun main(args: Array<String>) {
    Test()
}

输出是:1 0 3 2,这与Java相同,声明和初始化是两个不同的步骤,但对于Kotlin的主要构造函数来说这是奇怪的,呃......

3 个答案:

答案 0 :(得分:1)

从我的观点来看,它不是与kotlin有关,而是与JVM字节码有关,它实际上没有变量的“初始化”,它只是在构造函数中填充它们,你可以用一些反编译器检查它。

答案 1 :(得分:1)

这是从迈克尔的评论中扩展而来,该评论引用了Kotlin documentation

  

请注意,初始化程序块中的代码有效地成为主构造函数的一部分。对主构造函数的委派作为辅助构造函数的第一个语句发生,因此所有初始化程序块中的代码在辅助构造函数体之前执行。即使该类没有主构造函数,委托仍然会隐式发生,并且仍然会执行初始化程序块。

换句话说,init()块与(隐式)主构造函数关联,该构造函数作为辅助构造函数的第一行执行。 -kf

答案 2 :(得分:0)

您的示例看起来有点不一致。它是由一个事实引起的,第一个例子没有主要构造函数,但第二个例子有一个。但是,https://youtrack.jetbrains.com/issue/KT-22317已创建。