実行時にアノテーションを読み取る
Kotlinリフレクションを使って宣言からアノテーションのインスタンスを取得します。
「実行時にアノテーションを読み取る」はCoddyKit上の無料Kotlin Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはKotlin Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Kotlin Academyコースには全4レッスンが含まれています。
前提条件
実行時にアノテーションを読み取るには、次のものが必要です。(1) @Retention(RUNTIME)を付けて宣言したアノテーション、(2) クラスパス上のkotlin-reflect依存関係、(3) アノテーションが付いた要素へのKClass、KFunction、またはKProperty参照です。
KClassからアノテーションを読み取る
KClassに対してannotationsを呼び出すと、そのクラスに付いたすべてのアノテーションを取得できます。特定の型にはfindAnnotation<T>()を使用します。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
annotation class Table(val name: String)
@Table(name = "users")
class UserEntity
val ann = UserEntity::class.findAnnotation<Table>()
println(ann?.name) // "users"プロパティからアノテーションを読み取る
KProperty.annotationsまたはfindAnnotation<T>()を使って、プロパティのアノテーションにアクセスします。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)
data class User(@Column("user_name") val name: String)
val prop = User::name
val col = prop.findAnnotation<Column>()
println(col?.name) // "user_name"関数からアノテーションを読み取る
KFunction.findAnnotation<T>()を使って、関数に付いたアノテーションを読み取ります。
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class Transactional
class UserService {
@Transactional
fun save(user: User) { /*...*/ }
}
val fn = UserService::save
val isTx = fn.hasAnnotation<Transactional>()
println(isTx) // trueすべてのプロパティを調べてアノテーションを取得する
よく使われるパターンは、クラスで宣言されたすべてのプロパティを調べ、特定のアノテーションが付いたものを収集することです。
fun <A : Annotation> KClass<*>.annotatedProperties(
annotationClass: KClass<A>
): List<Pair<KProperty1<*, *>, A>> =
declaredMemberProperties
.mapNotNull { prop ->
prop.findAnnotation(annotationClass)?.let { ann -> prop to ann }
}パラメータのアノテーションを読み取る
KFunction.parametersを使って、コンストラクタパラメータのアノテーションにアクセスします。
class Repo(
@param:Validate(minLength = 3) val name: String
)
val ctor = Repo::class.primaryConstructor!!
val param = ctor.parameters.first()
val ann = param.findAnnotation<Validate>()
println(ann?.minLength) // 3hasAnnotationとfindAnnotation
真偽値だけを確認する場合はhasAnnotation<T>()を使用し、アノテーションのプロパティ値が必要な場合はfindAnnotation<T>()を使用します。どちらもkotlin.reflect.fullの拡張関数です。
クラス階層をたどる
スーパークラスやインターフェースのアノテーションは、Kotlinリフレクションでは自動的に継承されません。継承されたアノテーションが必要な場合は、KClass.superclassesをたどるか、KClass.allSuperclassesを使用する必要があります。
fun KClass<*>.findAnnotationRecursive(ann: KClass<out Annotation>) =
generateSequence(this) { null } // simplified — real impl walks supers
.flatMap { it.annotations }
.firstOrNull { it.annotationClass == ann }パフォーマンス
リフレクションの呼び出しは低速です。フレームワークの起動時にアノテーションを調べる場合は、結果をKClassをキーとするマップにキャッシュしてください。リクエストごと、またはフレームごとに実行される処理でアノテーションを読み取ることは避けてください。
use-siteターゲットとJVMフィールド
@field:ターゲットを持つプロパティのアノテーションは、JVMのバッキングフィールドに置かれます。Kotlinの宣言サイトだけを対象とするannotationsリストではなく、Javaリフレクション(KProperty.javaField?.annotations)を使ってアクセスしてください。
実践例:シンプルなORMマッパー
小さなORMマッパーが@Columnアノテーションを読み取り、SQLのカラムリストを構築します。
fun columns(klass: KClass<*>): String =
klass.declaredMemberProperties
.mapNotNull { it.findAnnotation<Column>()?.name }
.joinToString(", ")
println(columns(User::class)) // "user_name, email"クイックチェック
KClassから、MyAnn型の特定のアノテーションをどのように読み取りますか?
まとめ:実行時にアノテーションを読み取る
主なポイント:
- アノテーションには
@Retention(RUNTIME)が必要 findAnnotation<T>()でアノテーションの値を取得し、hasAnnotation<T>()で真偽値を確認するKClass、KFunction、KProperty、KParameterで使用できる- リクエストごとのオーバーヘッドを避けるため、起動時にスキャン結果をキャッシュする
@field:アノテーションにはKProperty.javaFieldを使用する
よくある質問
「実行時にアノテーションを読み取る」レッスンは無料ですか?
はい。「実行時にアノテーションを読み取る」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Kotlin Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Kotlin Academyコースには全4レッスンが含まれています。
「実行時にアノテーションを読み取る」で何を学びますか?
Kotlinリフレクションを使って宣言からアノテーションのインスタンスを取得します。 ブラウザで直接実行するハンズオンコードでKotlin Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Kotlin Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのKotlin Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「実行時にアノテーションを読み取る」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このKotlin Academyレッスンでコードを書いて実行できますか?
はい。すべてのKotlin Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Kotlin Reflection:KClass、KFunction、KProperty
- カスタムアノテーションの作成と対象指定
- 実行時にアノテーションを読み取る
- リフレクションベースのバリデーションとマッピング