Notasyonlar (Annotations) Java 5’den beri Java ortamında kullanılan bileşenlerdir. Notasyonlar genel olarak bir bileşene özellik katma veya konfigürasyon amaçlı olarak kullanılmaktadır. Bu yazıda notasyonların genel özelliklerinden ve Java 8 Repeated Annotations yeniliğinden bahsedilecektir.
Notasyonlar @
işaretiyle başlayan arayüzlerdir ve notasyonlar içinde alanlar tanımlanabilmektedir.
Örneğin;
public @interface Single {
String value();
}
Notasyonlar çeşitli alanlara uygulanabilmektedir. Bu alanlar;
Nereye uygulanabilir? | Açıklama |
---|---|
TYPE |
Sınıf, arayüz, soyut sınıf başlarına |
METHOD |
Metod başlarına |
FIELD |
Global alan başlarına |
PARAMETER |
Metod parametrelerine |
CONSTRUCTOR |
Constructor başına |
ANNOTATION_TYPE |
Notasyonların başına |
PACKAGE |
Paket deklarasyonu başına |
Hangi notasyonun nereye veya nerelere uygulanabileceği, notasyonu yazan tarafından belirtilmektedir. Bu belirtim işlemi ise @Target
isimli notasyon ile sağlanmaktadır.
@Target({ElementType.METHOD})
public @interface Single {
String value();
}
@Single
notasyonunun uygulanabilirlik alanı METHOD
olarak tanımlandığı için, @Single
notasyonu sadece metod başlarında kullanılabilir. Diğer alanlarda kullanılamaz, kullanılmaya kalkışılırsa derleme zamanında hata alınır.
@Single // Buraya konamaz
public class App {
@Single // Buraya konabilir
public void doIt() {
}
}
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Single {
String value();
}
Şimdi ise @Single
notasyonu hem metod başlarına hem de sınıf, arayüz, soyut sınıf gibi bileşenlerin başlarına eklenebilir.
@Single // Artık buraya da konabilir
public class App {
@Single // Buraya uygulanamaz :(
String message = "Merhaba Dünya";
@Single // Buraya konabilir
public void doIt() {
}
}
@Target
notasyonu ile yapılan aslında, notasyonun uygulanabilirlik alanını, yani yetki alanını belirlemektir. Örneğin Uygulama 2'de uygulanabilirlik alanı olarak METHOD
ve TYPE
belirlenmiştir. Bu sebeple sadece bununla ilgili kısımlara @Single
notasyonu uygulanabilir.Mesela örnekte olduğu gibi global alanlara uygulanamaz. Eğer buraya da uygulanabilir olması istenirse FIELD
enum bileşeni @Target
notasyonuna eklenmelidir.
Notasyonlar konfigürasyon amacıyla kullanılırken, barındırdığı değişken alanlarından faydalanılmaktadır. Bu alanların tipi, ismi ve gerekirse varsayılan değeri tanımlanabilmektedir.
Fakat bu alanlarda tip sınırlaması vardır, bu tipler şunlar olabilir;
String |
Temel tipler |
Class |
Bir Enum tipi |
Diğer bir notasyon tipi |
Yukarıdaki tiplerin dizi tipleri |
@Single
notasyonunu düşünürsek String
türünde value
adında tek bir alana sahiptir. Değer ataması ise deklerasyon anında ()
içerisinde yapılmaktadır.
@Single(value="Merhaba Dünya")
public interface Hello {
}
Notasyonlar için value
alanının özel bir anlamı vardır. Eğer başka bir alana değer ataması yapılmayacaksa value
yazılmasa bile bu değer ataması value
alanına yapılmaktadır.
@Single("Merhaba Dünya") (1)
public interface Hello {
}
-
Denktir
@Single(value="Merhaba Dünya")
Notasyonların nereye uygulandıkları ve içerisinde barındırdıkları veriler derleme zamanında (compile time) veya çalışma zamanında (runtime) elde edilebikmektedir. Fakat bir notasyona hangi zamanlarda erişilebileceği @Retention
isimli notasyon ile belirtilmelidir. Retention (tutma) politikasının 3 tipi vardır.
- SOURCE
-
Notasyonlar derleme zamanında yok sayılır.
- CLASS
-
Notasyonlar derleme zamanında sınıf içerisinde bulundurulur, fakat çalışma zamanında bulunması zorunlu değildir. Varsayılan hal budur.
- RUNTIME
-
Notasyonlar çalışma zamanında erişilmek üzere sınıf içerisinde bulundurulur. Çalışma zamanında erişim Java Reflection API ile yapılır. Sık kullanılan hal budur.
- Not
-
Rastgele 10 notasyon belirleyip, @Retention notasyonunu incelediğinizde %90 üzeri ağırlıkta tutma politikasının
RUNTIME
olarak yapılandırıldığını görebilirsiniz.
@Target({ElementType.METHOD, ElementType.TYPE}) (1)
@Retention(RetentionPolicy.RUNTIME) (2)
public @interface Single {
String value();
}
-
Metod ve Sınıfların başına uygulanabilir.
-
Çalışma zamanında bu notasyona erişilebilir.
Yukarıda @Target
ve @Retention
notasyonlarıyla yapılandırılmış kullanıma hazır bir @Single
notasyonunu görüyoruz.
Java 8 öncesinde bir notasyon, iki kere aynı yerde kullanılamamaktaydı.
@Single("Merhaba")
@Single("Jupiter")
public class App {
}
Örneğin @Single
notasyonu yukarıdaki gibi aynı alanda kullanılamaz. Bu sınırlılık Java 8 öncesinde ikincil bir notasyon üzerinden aşılmaktaydı.
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Multiple {
Single[] value();
}
Multiple notasyonu Single
tipli diziler barındırabilen bir value
alanına sahiptir. Artık Multiple notasyonu üzerinden birden fazla @Single notasyonu uygulanabilirdir.
@Multiple(value = {
@Single("Merhaba"),
@Single("Jupiter")
})
public class App {
}
NOTE : Notasyonlarda dizi tipli alanlara atamamalar, { }
arasında virgül , ile ayrılmış olarak yapılmaktadır.
Java 8 ile birlikte bu sınırlılık ortadan kalkmıştır. Bu sınırlılığı ortadan kaldırmak için @Repeatable
notasyonundan faydalanılmaktadır.
@Repeatable(Multiple.class) // Dikkat
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Single {
String value();
}
@Repeatable
notasyonu tekrarlayacak notasyona uygulanmaktadır. @Repeatable
ntoasyonunun value alanına ise, sarmalayıcı notasyonun sınıf tipi tanımlanmalıdır. Bu yolla tekrarlı notasyonlar alt alta, yan yan istendiği kadar tanımlanabilmektedir.
@Single("Merhaba")
@Single("Uranüs")
public class App {
public static void main(String[] args) {
Class<App> app = App.class; (1)
Single[] notz = app.getAnnotationsByType(Single.class); (2)
for (Single not : notz) { (3)
System.out.println(not.value()); (4)
// Merhaba
// Uranüs
}
}
}
-
App sınıfının sınıf tipini alır.
-
App sınıfına uygulanmış tüm Single tipli notasyonları bulur.
-
Tüm uygulanmış Single notasyonlarını dolaşır.
-
O anki Single notasyonunun value() alanını çıktılar.
Tekrar görüşmek dileğiyle.