プロパティ
Properties
プロパティの宣言
var
キーワードは、変更可能。val
キーワードは、読み取り専用となる。
class Address { var name: String = "Holmes, Sherlock" var street: String = "Baker" var city: String = "London" var state: String? = null var zip: String = "123456" }
プロパティを使うには、その名前を通してかんたんに参照する。
fun copyAddress(address: Address): Address { val result = Address() result.name = address.name .... return result }
GetterとSetter
プロパティのフルシンタックスは以下になる。
var プロパティ名[: 型] [= 初期化] [get()] [set(value)]
get()を使うことで、Computed property(計算プロパティ)を宣言することができる
val isEmpty: Boolean get() = this.size == 0
setter
var stringRepresentation: String get() = this.toString() set(value) { field = value }
プロパティの型は、getterから推測できる場合は、省略できる。
val isEmpty get() = this.size == 0
アクセス権(visibility)の変更もしくは、それに対するアノテートをする必要があるが、デフォルトの実装に変更は必要としない場合、その本体を宣言することなくアクセッサーを定義することができる。
// setterをprivateに変更する var setterVisibility: String = "abc" private set // setterにアノテートをつける var setterWithAnnotation:Any? = null @Inject set
Backing fields
Kotlinでは、フィールドは値を保持するためのプロパティの一部としてのみ使用される。 フィールドを直接宣言することはできない。
しかしながら、プロパティは背後のフィールドを必要とすることがある。 Kotlinは自動的にそれを提供する。
この背後のフィールドはfield
識別子を使ってアクセッサー内部で参照することができる。
var counter = 0 // 初期化は、背後のフィールドに直接値を代入する set(value) { if (value % 2 == 0) field = value else filed = value + 1 }
Backing properties
暗黙のbacking fieldを使いたくない場合は、backing propertyを使って同じことができる。
// backing property private var _table: Map<String, Int>? = null public val table: Map<String, Int> get() { if (_table == null) { _table = HashMap() } return _table ?: throw AssertionError("Set to null by another thread") }
コンパイル時定数
const
修飾子を使うことによって、コンパイル時の定数であることをマークすることができる。
ただし以下の条件がある。
- トップレベルもしくは、
object
宣言のメンバ もしくは、companion object
String
もしくは基本型による初期化- getterを持たない
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated" // 定数は、アノテーションで使用することができる @Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }
遅延初期化プロパティと変数
lateinit
修飾子をつけることで、遅延初期化することができる。
public class MyTest { // lateinitをつけると初期化コードが不要となる lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } }
初期化済みかどうかは、.isInitialized
を使う
if (foo::bar.isInitialized) { println(foo.bar) }