29 Ekim 2015 Perşembe

Generics ve Wildcard

Java
Not : Java'da generic konusunu anlamak için Java Generics FAQs - Frequently Asked Questions  yazısına mutlaka bakmak gerekir.

Java'da generic ile kullanılan parametre tiplerine wildcard uygulanabiliyor. Bazı wildcard örnekleri

Collection<?> , List<? extends Number> , Comparator<? super String> and Pair<String,?>
Şimdi bu örneklerin ne olduğuna bakalım

Java'da generics için wildcard ve bound kullanılması ciddi şikayetlere sebep olmuş durumda.

Unbounded Wildcard
Kalıtım hiyerarşisine dikkat etmeyen sınırlandırılmamış wildcard anlamına gelir. Herhangi bir generic tip kullanan nesne, unbounded wildcard ile tanımlanmış nesneye atanabilir. Assignment compatible'dır. İki unbounded wildcard assignment compatible değildir!

ArrayList <?>       anyList    = new ArrayList<Long>();
ArrayList<String> stringList = new ArrayList<String>();
anyList    = stringList;
stringList = anyList;      // error

Nesne Ekleme
unbounded wildcard genellikle okuma işlemi için kullanılır. Örnekte Box sınıfı tipini bilmediği bir nesneyi kabul etmiyor. Ancak null eklenebilir.
Box<?> box = new Box<String>("abc");
box.put("xyz");     // error 
box.put(null);     // ok
Unbounded Wildcard Ne İçin Lazımdır
Tipini bilmediğimiz nesneleri okumak için kullanılır. Örnekte tipini bilmediğimiz listedeki nesneler print ediliyor.
public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}
Android'den de bir örnek verebiliriz. parent nesnesi AdapterView<?> olarak geçiliyor.
listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id)
  {....}

Bounded Wildcard
Java
Generics ve Bounded Wildcard yazısına taşıdım.

C#'ta Upper Bound Generics
Generics ve Wildcard yazısına taşıdım.

Sık Yapılan Hatalar
Kalıtım İlişkisi Olmayan Bir Sınıf Kullanmak
Bazen kalıtım kullanan generics kodlarında anlaması zor hata mesajları alınabiliyor. En sık karşılaşılanı
Bound mismatch: The type X is not a valid substitute for the bounded parameter Y of the type Z
gibi bir mesaj. Burada anlatılmaya çalışılan X ve Y arasında beklenen kalıtım ilişkisi olmadığı.

Raw Type Kullanmak
Örnekte  Number'dan türeyen nesneler isteyen bir metod var.
public static void organizeData(java.util.List<? extends Number> c) {
    //operation on the list
}
Bu metod, raw type kullanan bir liste ile çağrılabilir. Bu durumda Uncheked Type Conversion uyarısı alırız.
List newList = new LinkedList<>();
ClassName.organizeData(newList);


Hiç yorum yok:

Yorum Gönder