2015-11-13 11 views
13

私はKotlinのクラスの初期化について説明している言語定義の何も見つけることができませんでした。Kotlinクラスの初期化セマンティクスとは何ですか?

import java.util.Properties 

fun main(args: Array<String>) { 
    val out = MyClass() 
    out.fn() 
} 

class MyClass { 
    private val a = Properties() // 1 

    init { 
     fn() 
    } 

    public fun fn() { 
     println("Fn called. a = $a") 
    } 

    // private val a = Properties() // 2 
} 

このプログラムの実行結果は、プロパティが(1)または(2)で初期化されているかどうかによって変わります。

宣言の順序は言語に関連しており、この背後にある決定を理解したいと思っています。私の期待は、コンストラクタ本体が呼び出される前にプロパティが初期化されることです。

答えて

10

私の期待は、コンストラクタ本体が呼び出される前にプロパティが初期化されることです。

まあ、initブロックはconstructorではありません。これは、オブジェクトの初期化を実行できる別の構造であり、それらは[initial blocks]がプロパティ初期化子で宣言の順序で実行されます。

コンストラクタは、すべてのプロパティが初期化され、すべての初期化ブロックが実行された後に実行される異なるビーストです。次の例を見てください:

class A(val value: Int) { 
    constructor(): this(0) {   
     println("Constructor") 
    }  

    init { 
     println("Init block") 
    } 
} 

fun main(args: Array<String>) { 
    val a = A() 
} 

出力は次のとおりです。

Init block 
Constructor 

あなたが好きな場所あなたがinitブロックを配置することができます:constructor前か後に、 Aのコンストラクター(この例では2次コンストラクター)の前に常にが実行されます()。

+18

これは完全に正しいわけではありません。 'init'ブロックには、プライマリコンストラクタに含まれるコードが含まれています。あなたの例では、セカンダリコンストラクタが ':this(0)'構文を使ってプライマリコンストラクタに委譲するため、それらは実行されます。二次コンストラクタが一次コンストラクタに委譲しない場合、そのコンストラクタを使用してクラスが初期化されるときに 'init'ブロックは実行されません。 – yole

+1

こんにちはAga/Yole - あなたの答えに感謝します。私はおそらく私がKotlin n00bだと言っていたはずですが、それはおそらく私の質問からはっきりしています。 あなたの回答はどちらも言語に精通していると思います。 "プライマリコンストラクタにはコードを入れることはできません。初期化コードは初期化ブロックに置くことができます先頭に「init」キーワードが付いています。 ただし、初期化の順序については何も記載されていません。 (私が見ることができる) –

+1

@yole明確化のために感謝します。:) – aga

4

簡単に言えば、クラスのインスタンスが作成されると、親クラス(存在する場合)のコンストラクタが実行され、次に主コンストラクタが実行されます。

主コンストラクタは、クラス本体で宣言されたコードを上から下に実行します。また、名前が同じルールで利用可能になった:あなたはセカンダリコンストラクタを呼び出すと、それはそれはチェーンで構成されて主1(親コンストラクタを呼び出すことに似ている)の後に動作します

class Foo(a: String = "might be first" 
      val b: String = "second" + a) : Boo(a + b + "third"){ 
    var c = a + "fourth" + b 

    init {print("fifth: $c")} 

    val d = "sixth" 
    init {print("seventh: the end of the primary constructor"} 
} 

+1

と呼ばれています。順序を確実に言い換えると、「ほとんど」と「可能性があります」を削除して決定的な回答になることができます。または@agaからの回答を延期する –

関連する問題