ザクっと理解するKotlin バッキングフィールドとバッキングプロパティ
Kotlinは、Javaに代わる新しいプログラミング言語で、コードの効率性や可読性を向上させるためにいくつかの新しい機能を導入しています。
その中でも、バッキングフィールドとバッキングプロパティは、特に注目に値する機能の一つです。
初心者にもわかりやすいように、簡単なコードで解説してます。
バッキングフィールド
バッキングフィールドはプロパティの一部としてのみ使用され、メモリ内に値を保持する役割があります。
必要な時にKotlinにより自動で宣言され、開発者が直接的に宣言することはできません。
プロパティに対して読み取りが行われると、実際はバッキングフィールドから値を読み取っています。
また書き込みも同様にバッキングフィールドに書き込みをしています。
宣言される条件
バッキングフィールドが宣言されるのは下記2つのどちらかの場合です。
・プロパティがアクセッサー(ゲッターもしくはセッター)のどちらかのデフォルト実装を使用している場合
・カスタムアクセッサーがfieldを使用してバッキングフィールドを参照している場合
デフォルト実装とは簡単にいうとアクセッサーを触らないということです。
class Person {
var count = 0
}
この場合、countはデフォルトアクセッサーを使用しているのでバッキングフィールドが生成されます。
fieldを使用している例は上でもある通り、
class Person {
var count = 0
set(value) {
field = value * 2
}
}
このようにバッキングフィールドにアクセスしている場合です。
宣言されない特別な条件
valでプロパティを宣言した場合は、バッキングフィールドは宣言されません。
valで宣言したプロパティは、一度値が設定されたらそれ以上変更されることがありません。
そのためコンパイラはこのプロパティに対してバッキングフィールドを生成せず、定数値を使用します。
これによりプロパティが使用されるたびにメモリを消費する必要がなく、実行効率が向上します。
バッキングフィールドの参照
バッキングフィールドはセッターやゲッター内でfieldを使用して参照することができます。
class Person {
var count = 0
set(value) {
field = value * 2
}
}
fieldはプロパティのゲッターとセッターでしか使用できません。
バッキングプロパティ
バッキングプロパティとはバッキングフィールドの値を取得したり、変更したりするアクセッサーを持つプロパティのことを指します。
要するにデフォルトのゲッターとセッターはバッキングフィールドの値を取得し、変更しているため、これもバッキングプロパティです。
暗黙的に宣言されるデフォルトのバッキングプロパティの動作が要望を満たさない場合は変更が可能です。
class Person {
private var _name: String = ""
var name: String
get() = _name
set(value) {
if (value.isNotBlank()) {
_name = value
}
}
}
このコードではnameのデフォルトのアクセッサーを変更しています。
このようにデフォルトの実装内容が要望に沿わない場合は変更が可能です。
このコードはカプセル化の原則に則って実装されています。
カプセル化についてはこちら!
※デフォルトのゲッターとセッターを使ってprivateなプロパティの値取得や編集をするのは、関数呼び出しのオーバーヘッドを避けるためにJVMで最適化されます。
コメント