Press "Enter" to skip to content

Effective Java Madde 54: Null Yerine Boş Koleksiyon veya Dizi Döndürün

Aşağıdakine benzer metotlar sıklıkla karşımıza çıkmaktadır:

// Boş koleksiyonu simgelemek için null döndürüyor, yanlış!
private final List<Cheese> cheesesInStock = ...;

/**
* @return markette bulunan bütün peynirleri içeren bir liste döndürür
* eğer peynir kalmadıysa null döndürür.
*/
public List<Cheese> getCheeses() {
    return cheesesInStock.isEmpty() ? null : 
           new ArrayList<(cheesesInStock);
}

Yukarıdaki kodda peynir listesinin boş olduğu durumu özel bir durum gibi ele alıyoruz. Bu son derece gereksizdir. Bu, istemciyi de null denetimi yapmaya mecbur bırakacaktır:

List<Cheese> cheeses = shop.getCheeses();
if (cheeses != null && cheeses.contains(Cheese.STILTON)) {
    System.out.println("Jolly good, just the thing.");
}

Boş bir koleksiyon veya dizi yerine null döndüren bütün metotlar bu soruna yol açar. Hata yapmaya çok elverişlidir çünkü istemci null kontrolü yapmayı unutabilir. Çağrılan metot çoğu durumda bir veya daha fazla eleman döndürüyorsa böyle hatalar yıllar boyunca farkedilmeyebilir. Ayrıca, bir metotta boş koleksiyon yerine null döndürmek daha zahmetli bir iştir.

Bazen boş koleksiyon döndürmenin null döndürmeye kıyasla performans kaybına sebebiyet vereceği düşünülebilir çünkü boş da olsa bir koleksiyon yaratmanın bir maliyeti vardır. Bu yaklaşımın iki problemi vardır. Birincisi, eğer performans kaybını ölçümlerle destekleyemiyorsanız bu seviyelerde endişelenmenize gerek yoktur. (Madde 67) İkincisi de bellekte ek yer işgal etmeden boş koleksiyonlar döndürmek mümkündür. Çoğu durumda yapmanız gereken tek şey budur:

// Boş koleksiyon döndürmenin doğru yolu
public List<Cheese> getCheeses() {
    return new ArrayList<>(cheesesInStock);
}

Eğer boş koleksiyon üretmenin maliyeti gerçekten uygulamanızın performansını etkiliyorsa, değiştirilemez (immutable) bir boş koleksiyonu tekrar tekrar kullanabilirsiniz çünkü değiştirilemez nesneler serbest bir biçimde paylaşılabilir. (Madde 17) Aşağıdaki kod Collections.emptyList metodunu kullanarak bunu yapmaktadır. Küme (set) döndürüyor olsaydınız Collections.emptySet, map döndürüyor olsaydınız da Collections.emptyMap kullanabilirsiniz. Ancak bunun küçük bir iyileştirmeden ibaret olduğunu unutmayın, eğer farkı ölçebiliyorsanız kullanın:

// İyileştirme - boş koleksiyon yaratılmasını engeller
public List<Cheese> getCheeses() {
return cheesesInStock.isEmpty() ? Collections.emptyList()
           : new ArrayList<>(cheesesInStock);
}

Dizilerdeki durum da koleksiyonlarla aynıdır. Uzunluğu sıfır olan dizi yerine null değeri döndürmeyin. Eğer dizinin elemanı yoksa uzunluk değeri sıfır olmalıdır, bu son derece geçerli bir kullanımdır. Aşağıdaki örnekte sıfır boyutlu bir diziyi toArray metoduna geçiyoruz. Bu aslında toArray metodundan istediğimiz dönüş türünü bildirmektedir, yani Cheese[]:

// Boş olması muhtemel bir dizi döndürmenin doğru yolu
public Cheese[] getCheeses() {
    return cheesesInStock.toArray(new Cheese[0]);
}

Eğer boş dizi yaratmanın performansı etkilediğine inanıyorsanız, aynı boş diziyi tekrar tekrar döndürebilirsiniz çünkü boş diziler de değiştirilemez nesnelerdir:

// İyileştirme - boş dizi yaratılmasını engeller
private static final Cheese[] EMPTY_CHEESE_ARRAY = new Cheese[0];
public Cheese[] getCheeses() {
    return cheesesInStock.toArray(EMPTY_CHEESE_ARRAY);
}

İyileştirilmiş versiyonda cheesesInStock listesinde eleman olsun veya olmasın aynı boş diziyi toArray metoduna geçiyoruz. Eğer cheesesInStock listesi boş ise o zaman geçtiğimiz boş dizi metottan döndürülecektir. Burada performansı iyileştireyim düşüncesiyle toArray metoduna geçilen diziyi önceden yaratmayı denemeyin, bu tam tersine performansı olumsuz etkileyecektir:

// Bunu yapmayın - diziyi önceden yaratmak performansı kötü etkiler
return cheesesInStock.toArray(new Cheese[cheesesInStock.size()]);

Özetle, boş koleksiyon veya dizi yerine asla null döndürmeyin. Bu API’ınızın kullanımını hem zorlaştırır hem de hata ihtimalini artırır. Performans katkısı da sağlamaz.

Share

Leave a Reply

%d bloggers like this: