Annotation (açıklama); koda metadata eklemek için kullanılan bir arayüzdür (interface) ve bu nedenle herhangi kod içermez. Açıklamalar aslında kodun çalışma şeklini değiştirmez. Çalışma ve ya derleme zamanlarında farklı araçlar tarafından kullanılmak için tanımlanırlar. Tanımlanması şu şekildedir;
annotations class FooBar
Annotation şu tanımlamaları alabilir;
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class FooBar
@Target : Açıklama eklenebilecek olası öğe türlerini belirtir (sınıflar, işlevler, özellikler ve ifadeler gibi);
@Retention : Açıklamaların saklanma durumunu belirler. Olası seçenekler; SOURCE, BINARY, RUNTIME . Ön tanımlı olarak RUNTIME şeklindedir
@Repeatable : Açıklamanın aynı öğe için birden fazla tanımlanmasını belirler.
@MustBeDocumented : Açıklamanın genel API parçası olduğunu ve belgelendirilmesi gerektiğini belirtir.
Açıklamaların İşlenmesi
Açıklamaların nasıl ve ne amaçla kullanıldığını anlamak için örnekleyelim. Positive isminde bir açıklama ve Item isminde bir sınıfı tanımlayarak,
annotation class Positive
class Item(val amount: Float, val name: String)
Bu açıklamanın Item isminde tanımlanan sınıf içerisindeki değerlerin geçerli olup olmadıklarını kontrol etmek için kullanabiliriz.
class Item(
@Positive val amount: Float,
@AllowedNames(["Alice", "Bob"]) val name: String)
Derlenme aşamasında, Item sınıfının özelliklerini ve bu özelliklere tanımalanan açıklamaları şu şekilde alabiliriz;
val fields = item::class.java.declaredFields
for (field in fields) {...}
for (annotation in field.annotations) {...}
Eğer bu özelliklerde aradığımız açıklamayı yakalarsak,
field.isAnnotationPresent(AllowedNames::class.java)
Tanımlanan değerleri alarak kontrol edebiliriz;
val allowedNames = field.getAnnotation(AllowedNames::class.java)?.names
Kaynaklar: