Soru NULL döndüren alternatifler


   /**
     * Returns the foo with the matching id in this list
     * 
     * @param id the id of the foo to return
     * @return the foo with the matching id in this list
     */
    public Foo getFoo(int id)
    {
        for (Foo foo : list)
        {
            if (foo.getID() == id)
            {
                return foo;
            }
        }

        return null;
    }

Geri dönmek yerine null ne zaman foo bulunamadı, değil mi throw bir exception? Önemli mi ve konuyla ilgili "en iyi uygulamalar" deyimi var mı? Bu arada, benim örneğimin biraz tartışmalı olduğunu biliyorum, ama umarım fikrini alırsın ...

Teşekkürler.

DÜZENLE

Değiştirilecek kod Foo dayalı İD Gerçek dünya senaryosunu daha iyi betimlemek.


25
2018-05-12 16:19


Menşei


Bir dil tasarımcısının hiç bir zaman boş değeri kabul etmeyeceğini söyleyen bir yorum var. Sebeplerinin ne olduğunu hatırlayamıyorum. - James P.
@James P: O CAR Hoare idi, işte bir alıntı: lambda-the-ultimate.org/node/3186 - Nathan Hughes
NULL OBJECT PATTERN kullanabilirsiniz. İhtiyacınız olup olmadığını kontrol et en.wikipedia.org/wiki/Null_Object_pattern   Uyarı ... Bu program, hatalar / hatalar normal program yürütme olarak görünebildiğinden dikkatli bir şekilde kullanılmalıdır. [5] - Sandeep G B
Uygulamamayı dilemek null Bir sürü silahın kendini vurduktan sonra bir tabanca tasarlamadığını dile getiren bir silah üreticisi gibiydi. - Yuck


Cevaplar:


Geri dönen null işlemek için sadece daha basit değil, daha iyi performans gösterir. İstisnalar işlemek için kullanılmalıdır olağanüstü vakalar.


21
2018-05-12 16:26



Bu önemli bir nokta. Foo içeriyorsa önceden bilmiyorsanız, null genellikle daha iyidir. Foo'nun listede olmasını her zaman bekliyorsanız, bir istisna daha uygun olabilir. - DHall
Katılmıyorum. Null'lardan dönmek ve kontrol etmek genellikle bir koku. Boş nesne kalıbı güzel yardımcı olabilir. - Finglas
Bana Etkili Java öğelerinden birini hatırlatır: Mümkün olduğunda Boş Bırak ( javapractices.com/topic/... ) - obaqueiro
Evet, kaçınılmalıdır ... Ama mR'nin sorusu neyin dönüşü arasında seçim yapılacağını veya bir istisna attığını ifade eder. Diğer etkili java öğesi (ve çok verimli) istisna atma istisnası değildir, çünkü bir hesaplama maliyeti vardır. Daha kaliteli bir ürünü mümkün olduğunca sunmak için tasarım ve performans dengelemelisiniz. - Ronye Vernaes


Yöntemin semantiğine bağlı olduğunu söyleyebilirim.

İrade foo neredeyse her zaman listede bulunabilir mi? (örneğin, sonlu miktarda nesne barındıran bir önbellekse). Öyleyse, bulunamadıysa, bir şeylerin yanlış gittiği anlamına gelebilir - örneğin, bazı uygulama başlatma işlemi başarısız oldu veya anahtar geçersiz - ve bir istisna geçerli olabilir.

Çoğu durumda, ancak, ben dönecekti null. Belki de müşteri nesnenin orada olmayabileceğini ve bu davayı ele almak için kodlanmış bir mantığa sahip olduğunu bilir; Bir istisna kullandıysanız, bu kodun okunması, anlaşılması ve sürdürülmesi çok daha zor olacaktır.

Bazı API'ler aslında iki yöntem sağlar: find null döndüren yöntem ve get veya load bir istisna atar.

Hmmm ... şüphe edildiğinde, nr lehine err :)


11
2018-05-12 16:26



İçin +1 find. Bu sözleşmeyi tercih ederim çünkü find öğenin eksik olabileceğini ima eder. get Öte yandan, arayanın bir öğenin iade edilmesini beklediği ve eğer orada değilse, muhtemelen bir yanlışlık olduğu anlamına gelir. - ollb


Geri dönen null geçerli bir sonuç olarak belgelenmiş ise, iyidir.

Başka bir seçenek, boş nesne kalıbıdır. Yani - bir örneği Foo herhangi bir veri yok:

public class Foo {
    public static final Foo NULL_FOO = new Foo();
}

ve yerine döndür.


5
2018-05-12 16:24



Bu, hataları gizlemek için harika bir yol gibi görünüyor. - Isaac Truett
@ Isaac: Bir yakalama boş bırakılırken olduğu gibi sessiz bir hata mıdır? - James P.
@Bozho: Bunu nasıl kullanıyorsunuz? Bir yöntemde sadece bir Foo.NULL_FOO döndürür müsün? - James P.
Bir blogda, bazı çerçevelerle .NET'te kullanılan benzer bir desen hakkında bir şeyler okuduğumu ekleyeceğim. Geliştiriciye göre, yalnızca geri dönüş nesnesinin bazı varsayılan değerlerle başlatıldığını bulmak için bir hatayı izlemeye çok zaman harcadıkları için sorunlu olduğu ortaya çıktı. Bu nedenle, bu yaklaşımı benimserseniz, varsayılan değerleri kullanmaktan kaçınmanız iyi bir fikir olacaktır. - James P.
@Isaac Truett, birçok kişi tarafından kullanılan bir seçenektir. Boş nesne kalıbı denir. Bazı durumlarda kullandım, mükemmel çalışıyor. Sadece onu ne zaman kullanacağına dikkat etmelisin. - Bozho


Geri dönmeyi tercih ederim null. Bu, bir yöntemden dönmek için mükemmel bir sonuçtur ve yöntem çağrılan kodunuz, boş değerleri uygun şekilde işlemelidir. Bu, çağrı kodunuza bir istisna atmak anlamına gelebilir, ancak bunu bu yöntemde yapmam.

Bu şekilde, eğer bir başkası sizin yönteminizi çizginin aşağısına çağırmak istiyorsa, boş değerleri, seçtikleri takdirde sizden farklı bir şekilde ele alabilirler. Eğer attıysanız ve istisna oluşturduysanız, başka bir programcıyı kodlarını istediklerinden farklı bir şekilde değiştirmeye zorlayabilir.

Elbette, bir şey boş olduğunda bir istisna atmanın mantıklı olabileceği bazı durumlar vardır (örneğin, bir bağlantı nesnesi veya bunun gibi bir şey, aslında bir değere sahip olmanız ve eğer bir şey yapmamanız demektir) yanlış). Ancak, bir başparmak kuralı olarak, çoğu durumda boş dönen iyi olmalıdır.


4
2018-05-12 16:21



eğer geri dönerse nullBunu kodun içinde bir yerde belgelemeli miyim? Ek bir yorum olarak belki? - mre
Daha sonra bir karışıklık noktası olabileceğini hissediyorsan, yapabilirdin. Her zaman bir yöntemin boş bir değer döndürmesini ve kodunuzda uygun şekilde ele almasını beklemelisiniz. - Robert Greiner
Bunu bahsetmelisin @return Javadoc'un bir parçası. - Peter Lawrey


Yapabiliyorsanız istisnaları önlemek en iyisidir, ancak bazen yapamazsınız. Bu durumda ne sakladın? null listede? 'Bulunamadı null' ile 'ne istediğini bulamadım' arasındaki farkı anlatamazsın.

Bir desen var, denir Seçenek Türleri ve Scala'da çok kullanılıyor. Öğeyi bir kapsayıcıyla veya 'Ben boş'um' yazan bir sınıfın kapsayıcısını döndürürsünüz. Viki makalesi daha iyi bir fotoğraf verecektir.

Ayrıca 'bu koleksiyonda var mı?' Bir bool döndüren bir yöntem, sonra ilk kodu kontrol etmediyseniz, yukarıdaki koddan bir istisna atar.


Ve sadece asıl sorununla tamamen alakasız bir yorum. Eşittirler, yalnızca iki nesne aslında eşit olarak kabul edilirse, doğru olarak geri dönmelidir. Bu nedenle yukarıdaki kod, ona geçirdiğiniz nesneyi daima iade etmelidir!


4
2018-05-12 16:25



Düzenlememe bakın ve teşekkürler! :) - mre
Sadece bahsetmeyi düşündüm. Asıl sorununla ilgisi olmadığını biliyordum. - Joe


En iyi pactice Javadoc'ta söylemek null hiçbir eşleşme bulunmadığında geri döner.

Başka bir yaklaşım, boş olabilecek (ve birden fazlasına sahip olabilir) bir Eşleşme Listesi döndürmek olabilir. Ancak bu yaklaşımı sevmiyorum.

Başka bir yaklaşım, NULL_FOO tip Foo değerini döndürmek olabilir.

Sadece boşa dönmeyi tercih ederim.

Bunun bir yolu, değer ile ne yapacağınıza bakmak ve işlevi zenginleştirmek, böylece döndürülen değerin yöntemde kullanılmasına ve döndürülmemesine bakmaktır. Örneğin. Eğer değeri olan bir metodu çağırırsanız, sadece herhangi bir şeyi geri döndürme ihtiyacını ortadan kaldıran fonksiyonda arayın.


3
2018-05-12 16:24



Foo'nun NULL_FOO değeri Boş Nesne Kalıbı - MarkOfHall


majory senaryolara bağlıdır. Uygulamanızın kendisi üretici ve bu yöntemin tüketici ise o zaman ne yapmanız gerektiğine karar vermek size tamamen bağlıdır, Else yöntemi ve Müşteri ihtiyaçlarına dayalı karar vermeniz gerekir.


1
2018-05-12 16:24





Geri dönen null kesinlikle kabul edilebilir. Ekstra çift düzine tuşa basıp geri dönme ihtimalini belgeleyecektim null JavaDoc'ta.

Kontrol edilen istisna atma, yönteminizin çağrıldığı her yerde bu istisnayı denemeniz / yakalamanız veya yeniden atmanız gerektiği anlamına gelir. Denetlenmeyen bir istisna, özellikle de bir NPE'den başka bir şey, insanları şaşırtarak yakalayacak.


1
2018-05-12 16:25





Bu durumda, bir erişimciyi tanımladığınızdan, null döndürmelidir. Bu yöntemin sıfır olmayan bir yanıtı garanti etmesi gereken başka bir yöntem olsaydı, bir istisna daha uygun olurdu.

Ancak, bir yan not olarak, örnek yöntemi çağırmak yerine bir getter gibi bir şey gibi adlandırmak daha uygun olabilir Foo findFoo(Foo f) aradığınızdan beri aradığınızdan.


1
2018-05-12 16:25