Refleksjonsbasert validering og mapping
Bygg en enkel validator eller object mapper med annotasjonsdrevet refleksjon.
Refleksjonsbasert validering og mapping er en gratis leksjon i Kotlin Academy på CoddyKit. Dette er leksjon 4 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Kotlin Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Kotlin Academy inneholder totalt 4 leksjoner.
Hva dette mønsteret løser
Validering basert på refleksjon leser annotasjoner fra egenskapene til en klasse under kjøring og bruker valideringsregler automatisk – uten manuelle kontroller for hvert felt. Den samme teknikken brukes av ORM-mappere som konverterer mellom objekter og rader i databasen.
Annotasjonen Validate
Definer en annotasjon som beholdes ved kjøring, og som retter seg mot egenskaper:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Validate(
val minLength: Int = 0,
val maxLength: Int = Int.MAX_VALUE,
val pattern: String = ""
)Annotering av en dataklasse
Bruk @Validate på egenskapene i dataklassen. Validatoren skanner disse under kjøring:
data class UserForm(
@Validate(minLength = 2, maxLength = 50) val name: String,
@Validate(pattern = "^[\\w.]+@[\\w]+\\.[a-z]{2,}$") val email: String,
@Validate(minLength = 8) val password: String
)Validatorfunksjonen
Bruk KClass.declaredMemberProperties til å iterere over egenskaper, finne annotasjoner og samle inn feil:
fun validate(obj: Any): List<String> {
val errors = mutableListOf<String>()
for (prop in obj::class.declaredMemberProperties) {
val ann = prop.findAnnotation<Validate>() ?: continue
val value = (prop as KProperty1<Any, *>).get(obj)?.toString() ?: ""
if (value.length < ann.minLength) errors += "${prop.name}: too short"
if (value.length > ann.maxLength) errors += "${prop.name}: too long"
if (ann.pattern.isNotEmpty() && !value.matches(Regex(ann.pattern)))
errors += "${prop.name}: invalid format"
}
return errors
}Kjøre validatoren
Kall validate() med et vilkårlig annotert objekt. Funksjonen returnerer en liste med feilmeldinger. En tom liste betyr at objektet er gyldig:
val form = UserForm("A", "not-an-email", "short")
val errors = validate(form)
errors.forEach(::println)
// name: too short
// email: invalid format
// password: too shortObjekt-til-Map-tilordning med @Column
Et annet refleksjonsmønster tilordner et objekt til en Map ved hjelp av en @Column-annotasjon som oppgir kolonnenavn:
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.PROPERTY)
annotation class Column(val name: String)
fun toMap(obj: Any): Map<String, Any?> =
obj::class.declaredMemberProperties
.mapNotNull { prop ->
val col = prop.findAnnotation<Column>() ?: return@mapNotNull null
col.name to (prop as KProperty1<Any, *>).get(obj)
}.toMap()Bruke tilordneren
Annoter dataklassen og kall toMap() for å hente et kolonnenøkkelbasert map som er klart for en INSERT-setning:
data class User(
@Column("user_name") val name: String,
@Column("user_email") val email: String
)
val user = User("Alice", "alice@example.com")
println(toMap(user))
// {user_name=Alice, user_email=alice@example.com}Bufring av refleksjonsresultater
Refleksjonsskanninger er kostbare. Bufre tilordningen mellom egenskaper og annotasjoner ved oppstart ved hjelp av en ConcurrentHashMap med nøkkel av typen KClass:
val cache = ConcurrentHashMap<KClass<*>, List<Pair<KProperty1<Any,*>, Column>>>()
fun columnsOf(klass: KClass<*>) = cache.getOrPut(klass) {
klass.declaredMemberProperties
.mapNotNull { p ->
p.findAnnotation<Column>()?.let { (p as KProperty1<Any,*>) to it }
}
}Kombinere validering og tilordning
De kan legge flere annotasjoner på én egenskap og behandle hver av dem uavhengig. Valider først og tilordne deretter – eller gjør begge deler i én gjennomgang ved å samle hver annotasjonstype:
data class Product(
@Validate(minLength = 1) @Column("product_name") val name: String,
@Column("price") val price: Double
)Begrensninger
Refleksjonsbasert validering er kraftig, men har noen avveininger: Den gir ekstra belastning under kjøring, er avhengig av at annotasjonene beholdes, og kan ikke oppdage feil under kompilering. For validering som er kritisk for ytelsen eller skal være sikker under kompilering, bør De i stedet vurdere KSP-generert kode.
Når dette mønsteret bør brukes
Refleksjonsbasert validering er spesielt nyttig i rammeverkskode som må håndtere vilkårlige brukerdefinerte klasser: ORM-er, serializere, skjemavalidatorer og konfigurasjonsbindere. Programkode som selv eier typene sine, bør foretrekke eksplisitt validering for bedre ytelse og tydelighet.
Kort kontroll
Hvilken retensjonspolicy for annotasjoner kreves for at en valideringsannotasjon skal kunne leses under kjøring?
Oppsummering: Refleksjonsbasert validering og tilordning
Viktigste punkter:
- Deklarer annotasjoner som beholdes ved kjøring, og som retter seg mot egenskaper
- Bruk
declaredMemberProperties+findAnnotationtil å styre validering eller tilordning - Bufre resultater per
KClassfor å unngå gjentatt refleksjonsbelastning - Legg flere annotasjoner på en egenskap for kombinert atferd
- Vurder KSP som et alternativ ved kompilering i ytelseskritiske deler av koden
Lær deg Kotlin med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 51
- Leksjoner
- 203
Ofte stilte spørsmål
Er leksjonen «Refleksjonsbasert validering og mapping» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Kotlin Academy, inkludert «Refleksjonsbasert validering og mapping», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Kotlin Academy inneholder totalt 4 leksjoner.
Hva lærer jeg i «Refleksjonsbasert validering og mapping»?
Bygg en enkel validator eller object mapper med annotasjonsdrevet refleksjon. Du øver på Kotlin Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Kotlin Academy?
Ingen tidligere erfaring er nødvendig. Kotlin Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 4 av 4.
Hvor lang tid tar leksjonen «Refleksjonsbasert validering og mapping»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Kotlin Academy-leksjonen?
Ja. Alle Kotlin Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Kotlin-refleksjon: KClass, KFunction, KProperty
- Opprette og målrette egendefinerte annotasjoner
- Lese annotasjoner under kjøring
- Refleksjonsbasert validering og mapping