Kotlinメモ
staticフィールド
kotlinプロパティは名付けられたオブジェクト内かコンパニオンオブジェクトを含んでいるクラス内かどうかのstaticバッキングフィールドを持つ名付けられたオブジェクト内もしくはコンパニオンオブジェクト内で宣言される。
普通これらのフィールドはプライベートだけど、以下の方法で出すことができる:
@JvmFieldアノテーション
lateinit修飾子
const修飾子
@JvmFieldによるプロパティのようにアノテーションをつけることはプロパティ自信として同じ可視性と一緒にstaticフィールドにしてくれる。
code:kotlin
class Key(val value: Int) {
companion object {
@JvmField
val COMPARATOR: Comparator<Key> = compareBy<Key> { it.value }
}
}
code:java
// Java
Key.COMPARATOR.compare(key1, key2);
// public static final field in Key class
オブジェクト内もしくはコンパニオンオブジェクト内で初期化されたプロパティはプロパティセッターのように同じ可視性によってstaticバッキングフィールドを持つ。
code:kotlin
object Singleton {
lateinit var provider: Provider
}
code:java
// Java
Singleton.provider = new Provider();
// public static non-final field in Singleton class
プロパティはJavaでのstaticフィールドに変換された(トップレベルと同様のクラスで)constによって注釈される。
code:kotlin
// file example.kt
object Obj {
const val CONST = 1
}
class C {
companion object {
const val VERSION = 9
}
}
const val MAX = 239
code:java
int c = Obj.CONST;
int d = ExampleKt.MAX;
int v = C.VERSION;
staticメソッド
Kotlinはstaticメソッドみたいなパッケージレベル関数をだす。もし@JvmStaticのような関数にアノテーションをつけるなら、Kotlinは名付けられたオブジェクトかコンパニオンオブジェクト内で定義した関数によってstaticメソッドを生成することもできる。もしこのアノテーションを使うなら、コンパイラはオブジェクトの囲んでいるクラス内でstaticメソッドとオブジェクト自信内でのインスタンスメソッドの両方で生成する。
code:kotlin
class C {
companion object {
@JvmStatic fun foo() {}
fun bar() {}
}
}
fooはstaticでbarは違う。
code:kotlin
C.foo(); // works fine
C.bar(); // error: not a static method
C.Companion.foo(); // instance method remains
C.Companion.bar(); // the only way it works
名付けられたオブジェクトも同じ。
code:kotlin
object Obj {
@JvmStatic fun foo() {}
fun bar() {}
}
Javaでは、
code:java
Obj.foo(); // works fine
Obj.bar(); // error
Obj.INSTANCE.bar(); // works, a call through the singleton instance
Obj.INSTANCE.foo(); // works too
@JvmStaticアノテーションはコンパニオンオブジェクトを含んでいるオブジェクトもしくはクラス内でstaticメンバーであるゲッターとセッターメソッドを作っているオブジェクトのプロパティもしくはコンパニオンオブジェクト上で適用させることもできる。
lateinit
通常、プロパティはコンストラクタでの初期化されるのでnon-nullになっている。でもこれがあまり便利でなかったらしい。コンストラクタで変数の初期化をする際、nullの値の入った変数しか指定できない。さらにnullチェックを避けたいとき。
lateinitはvarを使用して変数を定義できる。Kotlin 1.2から出たらしい。型はnon-nullで、プリミティブ型ではない。
コンストラクタより後にnon-nullな値を初期化したいときに使う。(イベントドリブンな仕組みだとどうしても使うことになる)
lazyと違うのは、lazyはsetとnullな変数に使えるところ。
これを使うのはどうしてもnon-nullな値にしたいけど、コンストラクタで初期化はしたくない物を入れるためだけに使うのが吉だと思う。変数を使いたいときに値がなければ、uninitializedPropertyAccessExceptionがでる。
資料