0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Kotlin】Kotlin 拡張関数 × inline × reified 型パラメータ

Posted at

はじめに

Kotlin の強力な機能を組み合わせると、
型安全で、かつジェネリックなユーティリティ関数」を
簡潔に書くことができます。

その中心となるのが:

  • 拡張関数(Extension Function)
  • inline 関数
  • reified 型パラメータ

この3つを組み合わせることで、
Javaでは実現が難しい “型安全な動的処理” が可能になります。


まずは基礎を整理

inline 関数とは?

関数を「インライン展開」する機能。
呼び出し時に関数本体が直接展開され、関数呼び出しのオーバーヘッドが減ります。

inline fun measure(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    println("${System.currentTimeMillis() - start}ms")
}

reified 型パラメータとは?

通常のジェネリクスは「型消去(type erasure)」により、
実行時に型情報が失われます。

fun <T> printType(value: T) {
    println(value is String) // ✅ OK
    println(T::class)        // ❌ Error: reified が必要
}

→ 型パラメータ T実行時には存在しない ため、T::class は使えません。

そこで登場するのが reified 修飾子
inline と組み合わせることで、
実行時にも型情報を利用できるようになります。


基本構文

inline fun <reified T> printType(value: Any) {
    if (value is T) {
        println("value は ${T::class.simpleName} 型です")
    }
}

printType<String>("Hello")  // → value は String 型です
printType<Int>(42)          // → value は Int 型です

inline + reified の組み合わせにより、
T::classis T実行時にも有効 になります。


実践例①: Intent 拡張関数で型安全な遷移

Android 開発で頻出する Intent の生成。
通常は Class を明示して書きますが、reified で型安全にできます。

inline fun <reified T : Activity> Context.intentFor(): Intent {
    return Intent(this, T::class.java)
}

// ✅ 使用例
val intent = context.intentFor<DetailActivity>()
startActivity(intent)

これで:

  • Intent(this, DetailActivity::class.java) を短縮
  • ClassNotFoundException のようなミスを防止
  • 型推論で安全に扱える

さらに便利に:引数も安全に渡す

inline fun <reified T : Activity> Context.startActivityWith(vararg extras: Pair<String, Any?>) {
    val intent = Intent(this, T::class.java)
    extras.forEach { (key, value) ->
        when (value) {
            is Int -> intent.putExtra(key, value)
            is String -> intent.putExtra(key, value)
            is Boolean -> intent.putExtra(key, value)
            // 必要に応じて型を追加
        }
    }
    startActivity(intent)
}

// ✅ 使用例
startActivityWith<DetailActivity>(
    "userId" to 123,
    "name" to "Anna"
)

→ 型を安全に分岐させることで、
Intent 引数もスマートに管理できます。


実践例②: JSON 文字列 → 型安全なデシリアライズ

よくある「JSON → Model変換」にも reified は超便利です。
例として Gson を使います:

inline fun <reified T> String.fromJson(): T =
    Gson().fromJson(this, T::class.java)

// ✅ 使用例
data class User(val id: Int, val name: String)

val json = """{"id":1,"name":"Anna"}"""
val user = json.fromJson<User>()

println(user.name) // → Anna

→ 通常なら fromJson(json, User::class.java) と書くところを
型推論だけで安全に変換 できるようになります。


実践例③: 汎用 ViewModel 取得関数

Jetpack Compose や Hilt を使う場合にも reified は大活躍。

inline fun <reified VM : ViewModel> Fragment.viewModel(): VM {
    return ViewModelProvider(this)[VM::class.java]
}

// ✅ 使用例
val vm = viewModel<MainViewModel>()

→ 型を明示するだけで安全に取得可能。
リフレクション文字列指定のミスを完全防止。


注意点:inline と reified はセットで使う

  • reifiedinline 関数の中でのみ使用可能
  • 通常の関数では型情報が消えるため利用できません
// ❌ コンパイルエラー
fun <reified T> test() { }  
// → "Only type parameters of inline functions can be reified"

応用:型安全 Factory 関数

inline fun <reified T> createInstance(): T =
    T::class.java.getDeclaredConstructor().newInstance()

val user: User = createInstance() // 型推論で自動生成

T::class.java を使えるのは reified のおかげ。
リフレクションを安全に扱える。


まとめ

キーワード 説明
inline 関数呼び出しを展開し、パフォーマンス向上& reified と併用必須
reified 実行時に型情報を保持できる
拡張関数 既存クラスに自然に機能を追加できる
組み合わせ効果 型安全 × 冗長性削減 × 可読性向上

よくある組み合わせパターン

用途 関数例 備考
Activity起動 Context.intentFor<T>() 型安全なIntent生成
JSON変換 String.fromJson<T>() 汎用デシリアライザ
ViewModel取得 Fragment.viewModel<T>() ViewModelProvider連携
Factory生成 createInstance<T>() 型からインスタンス生成

終わりに

inline + reified + 拡張関数 の組み合わせは、
Kotlin の「表現力」と「安全性」を最大限に引き出すパターンです。

  • Javaの反射を置き換えるほど強力
  • Intent、JSON、DI、Factory… あらゆる場面で使える
  • Kotlinらしい「型安全 × シンプル」な設計

このパターンをマスターすれば、
Kotlinアプリ設計が一段階レベルアップします。


参考

  • Kotlin Official Docs: Reified type parameters
  • Android Developers: Kotlin Extensions (KTX)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?