Kotlinのプロパティに関して学びます。
プロパティはJavaでいうところのメンバ変数です。
例を見ましょう。
1 2 3 4 5 6 7 8 9 10 11 |
fun main(args: Array<String>) { var john = Person("john") // プロパティnameを参照 val johnName = john.name // john println(johnName) } class Person constructor(name: String) { var name = name } |
nameがプロパティになります。
Javaのメンバー変数と変わらないようです。
バッキングフィールド
先ほど、変わらないと書きましたが、実際プロパティはバッキングフィールドと呼ばれる入れ物
を持ちます。
先ほど定義したプロパティnameのStringの参照はバッキングフィールド内に
持っており、それらをプロパティを通じてアクセスすることになります。
カスタムセッター
では、カスタムセッターを用いて、バッキングフィールドにアクセスして見ましょう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
fun main(args: Array<String>) { var john = Person("") // カスタムセッターを用いる(john is set) john.name = "john" // john println(john.name) } class Person constructor(name: String) { var name = name set(value) { println("$value is set") // fieldにセットする field = value } } |
バッキングフィールドを持つプロパティが自動で値をセットするのでなく、
カスタムセッターを用いて、nameのfieldに値をセットすることができました。
プライマリコンストラクタにプロパティを持たせる
プライマリコンストラクタにプロパティを持たせることができます。
例を見て見ましょう
1 2 3 4 5 6 7 8 9 10 11 12 |
fun main(args: Array<String>) { var john = Person("jhon",19) // johnのプロパティにアクセス john.age = 20 // name:john age:20 println("name:" + john.name + " age:" + john.age); } // 修飾詞をつけて宣言する class Person constructor(val name: String,var age : Int) { } |
遅延初期化
Kotlinでは、初期値にnullが代入されることを防ぐ為に、プロパティを宣言する際にnull以外の値を代入する必要がありますが、lateinit keywordを使用することにより、プロパティに初期値を代入することなくプロパティを宣言することができます。
例を見ましょう
1 2 3 4 5 6 7 8 9 10 11 |
fun main(args: Array<String>) { var john = Person() // 怒られる:lateinit property name has not been initialized print(john.name) } // 修飾詞をつけて宣言する class Person constructor() { lateinit var name : String } |
上記では、初期化することなく、プロパティnameを宣言できていますが、
nameを初期化する前に参照しているため
UninitializedPropertyAccessException
が吐かれてしまいました。