Skip to content

Latest commit

 

History

History
249 lines (180 loc) · 7.3 KB

chapter-06.asc

File metadata and controls

249 lines (180 loc) · 7.3 KB

Notasyonlar ve Tekrarlı Notasyonlar

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;

@Single Notasyonu
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.

Örnek 1
@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.

Uygulama 1
@Single // Buraya konamaz
public class App {

    @Single // Buraya konabilir
    public void doIt() {

    }
}

Örnek 2
@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.

Uygulama 2
@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 ve Alanları

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.

Örneğin;
@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.

Örneğin;
@Single("Merhaba Dünya") (1)
public interface Hello {

}
  1. Denktir @Single(value="Merhaba Dünya")

Notasyonlara Erişim

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.

Örneğin;
@Target({ElementType.METHOD, ElementType.TYPE}) (1)
@Retention(RetentionPolicy.RUNTIME) (2)
public @interface Single {

    String value();

}
  1. Metod ve Sınıfların başına uygulanabilir.

  2. Ç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.

Notasyonların Tekrarlı Kullanılması

Java 8 öncesinde bir notasyon, iki kere aynı yerde kullanılamamaktaydı.

Hatalı kullanım örneği;
@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ı.

Örneğin;
@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.

Doğru kullanım örneği;
@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.

Örneğin;
@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
        }

    }

}
  1. App sınıfının sınıf tipini alır.

  2. App sınıfına uygulanmış tüm Single tipli notasyonları bulur.

  3. Tüm uygulanmış Single notasyonlarını dolaşır.

  4. O anki Single notasyonunun value() alanını çıktılar.

Tekrar görüşmek dileğiyle.