Ana içeriğe atla

Generics && wildcards

Genericsler java 5 ile gelen özellikler. Basit şeklini hemen hemen her yerde kullanıyoruz. ancak collection arayüzü ile beraber kullanımında bazen sıkıntı yaşandıgını görüyorum.

şöyle bir incelemek gerekirse;


class{
Collection myNUmbers = new ArrayList();
public void main() {
printCollection(myNUmbers);
}
void printCollection(Collection c) {
for (Serializable e : c) {
System.out.println(e);
}
}
}


printCollection(Collection c) methodunda parametre olarak "Collection c" almış olsaydı yukarıda ki kod parçası hata alacaktı.

çünkü eger extend kullanmazsak, collection ile beraberinde kullanılan generics betimi beraber bir class oluştruyorlar ancak bu inheritance özelliklerini desteklemiyor diye dusunebiliriz

yukarıda extend olmazsa ve biz
printCollection(myNUmbers); methodunu aynen çagırırsak hata alırız.

hatta ve hatta;


Collection myNUmbers = new ArrayList();

şekilde tanım yapıp


void printCollection(Collection < Object > c) {
for (Object e : c) {
System.out.println(e);
}
}

şu methodunu


printCollection(myNUmbers); // hata


çagırsak bile hata alırız.


birde asıl önemli bir genel karıştırılan konu!


Collection myNUmbers = new ArrayList();


şekilde tanım yapıp

yine birince tanımlandıgı şekilde


printCollection(myNUmbers);


bu propertyi methoda gönderip , methodun içinde deger ataması yapmaya çalışmak

c.add(new Long(1)); // hata

bu son hata ilk başta çok garip gelebilir. zaten aslında bu kod compile edilebilmesine ragmen mantıksal hatalardan ötürü engellenmiştir. yukarıda number property integer ve alt class larını almaktadır. biz bu property i printController methoduna gönderiyoruz ama Serializable üst sınırıyla collection tanımlıyoruz, yani içeride biz long da koyabilirz double de hata yok ama mantıksal olarak hata var. eger compile edilirse runtime da hata alabilirz. genericleri kullanmamızın bir anlamı kalmaz. bu sebeple methodlar da wildcard(?) olarak tanımlama yapıldıysa yeni eklemeler yapamayız ve genel anlamda super type ile işlemler yaparız.



kullanma koşulu olarak


private void print(Collection numbers) {
for (T nextNumber: numbers) {
System.out.println(nextNumber);
}
}

yazdıgımı zı düşünelim burda gelen T nin biizm için bir anlamı yok bu yüzden

bu kodu ? ile yazabiliriz


private void print(Collection numbers) {
for (Number nextNumber: numbers) {
System.out.println(nextNumber);
}
}

görüldügü gibi daha generic bir yol izlemiş olduk

gecenin bir vaktinde bu kadar
wilcard kullanın , keyfinize bakın ..

Yorumlar