2
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?

More than 3 years have passed since last update.

【Kotlin】kotlin-reflect無しでFunctionReference(KFunction)から情報を読み出す

2
Posted at

TL;DR

  • ::Constructorというような形で取得したKFunctionkotlin.jvm.internal.FunctionReferenceにキャストできる1
  • FunctionReferenceからはkotlin-reflect無しでも様々な情報を得ることができる
  • ただし、パッケージ名にも有る通り、internalな(= 外部から参照されることを想定していない)APIを参照することになるため、Kotlinの更新で壊れる可能性が有る点には注意が必要
    • 加えて、一部のメソッドはkotlin-reflect無しで呼び出すと実行時エラーになる点にも注意が必要

本文

基本的にキャストするだけで全ての情報が取得できるので、サンプルコードとコメントだけで詳細な説明は省きます。

import kotlin.jvm.internal.ClassBasedDeclarationContainer
import kotlin.jvm.internal.FunctionReference

// Sampleクラスのコンストラクタを使って呼び出す例
readInfoSample(::Sample as FunctionReference)

fun readInfoSample(ref: FunctionReference) {
    // メソッドの名前や引数の情報(signature形式)
    val name: String = ref.name
    val signature: String = ref.signature

    // methodでいう所のインスタンスパラメータ
    // objectや、${instance}::${method}の形で取得した場合、当該のインスタンスが返ってくる
    // インスタンスパラメータが設定されない/されていないメソッドの場合、FunctionReference.NO_RECEIVERのインスタンスが返ってくる
    val boundReceiver: Any = ref.boundReceiver

    // このFunctionReferenceを定義するclassまたはファイルの情報
    // 試した限りではnullやClassBasedDeclarationContainer以外の型にならない
    val owner: ClassBasedDeclarationContainer = ref.owner!! as ClassBasedDeclarationContainer
    // java classも読み出せる
    val jClass: Class<*> = owner.jClass
}

手元で検証した限り、コンストラクタ、インスタンス関数、トップレベル関数などについてはこの方法で情報を読み出せるようでした。
ただし、冒頭に記載した点には注意が必要です。

補足

jClassからMetadataアノテーションを取得し、kotlinx-metadata-jvmで解析することで、より詳細な情報を得ることもできます。

  1. KClassなどから読み出すパターンは想定していません。また、その場合取得できるのはKFunctionImplとなるため、この記事で紹介する方法は使えない可能性が有ります。

2
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
2
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?