KotlinDive

プログラミング言語 Kotlin についての入門ブログです。

リフレクション

リフレクションとは

リフレクションとは、プログラム内で宣言したクラスや関数、プロパティなどから、 それら自身の名前などの情報をプログラムの実行時に取得することです。
Kotlinでは、主に「::」を使ってリフレクションを取得します。

クラス

クラスのリフレクションを取得するには、クラスそのものやオブジェクトの後ろに「::class」をつけます。
「::class」には様々なメンバーがあり、対象となったクラスのいろいろな情報を取得することができます。

import kotlin.reflect.full.declaredMembers

fun main(args: Array) {
    println(Student::class)

    for (parameter in Student::class.declaredMembers) {
        println(parameter)
    }

    println("")

    // インスタンスからもリフレクションを取得可能
    val obj = Student("suzuki", 82.1)

    for (i in obj::class.members) {
        println(i)
    }
}

data class Student(val name: String, var score: Double)
 class Student
val Student.name: kotlin.String
var Student.score: kotlin.Double
fun Student.component1(): kotlin.String
fun Student.component2(): kotlin.Double
fun Student.copy(kotlin.String, kotlin.Double): Student
fun Student.equals(kotlin.Any?): kotlin.Boolean
fun Student.hashCode(): kotlin.Int
fun Student.toString(): kotlin.String

val Student.name: kotlin.String
var Student.score: kotlin.Double
fun Student.component1(): kotlin.String
fun Student.component2(): kotlin.Double
fun Student.copy(kotlin.String, kotlin.Double): Student
fun Student.equals(kotlin.Any?): kotlin.Boolean
fun Student.hashCode(): kotlin.Int
fun Student.toString(): kotlin.String

関数

ある関数を宣言した時、もちろんその関数を「test()」のような形で普通に呼び出すことができます。
一方、その関数自体を一種の「値」として別の関数に渡したい場合などは、「::test」とすることで、「test」関数への参照を取得することができます。
これは関数のリフレクションなので、関数自体の情報、つまり関数名や引数について知ることができます。

 fun main(args: Array) {
    val studentList = listOf("suzuki", "tani", "tanaka", "seki")

    // リフレクションで関数事態の情報を取得
    println(::checkLength.name)
    println(::checkLength.parameters)

    // 関数事態を一種の値として関数に渡す
    println(studentList.filter(::checkLength))
}

fun checkLength(str: String) = str.length > 5
 checkLength
[parameter #0 str of fun checkLength(kotlin.String): kotlin.Boolean]
[suzuki, tanaka]