型変数プログラミングのすゝめ
TL;DR: クラスレスリフレクションを活用してソースをよりスマートにしようという話。
型変数プログラミングとは?
型変数プログラミングとは、表面上はgetClass()
やclass
が一度もソース上に出てこないソースを書くことを指す。
例: arrayOf(): Array<E>
は一度もE::class.java
が出てこない (実態は、new E[]{}
をインライン展開しているだけ)
リフレクションと相性がいい理由
リフレクションで決まってよく出てくるgetClass()
。ボイラーコードが多くなりがち。そんなときに上記の例示のような型変数プログラミングを使うとスマートになる。
例
// SmartReflections.kt
inline fun <reified E> isArray(): Boolean = E::class.java.isArray
// TestReflections.kt
fun main() {
assertTrue {
isArray<IntArray>() // => true
}
}
注記事項
reified
はinline
とコンビでないと使えない。- そのためprivate関数は呼び出せない。
- 性質上、呼び出し元が全てインライン展開される。そのためあまり大きいコードを書くとバイナリのサイズが肥大化する。
- 型消去が走るので型変数がジェネリックだった場合はジェネリック部分が消去される。 例:
fun main() {
assertFalse {
isSameSigniture<() -> Int, () -> Double>() // falseだが、trueになりAssertionError
}
}
- そもそもリフレクションしないことが可能ならしないほうがいい。