Java veya C #'da istisna yönetimi için en iyi uygulamalar [kapalı]


117

Başvurumdaki istisnaların nasıl ele alınacağına karar vermede takılı kaldım.

İstisnalarla ilgili sorunlarım 1) uzak bir hizmet aracılığıyla verilere erişmekten veya 2) bir JSON nesnesinin serisini kaldırmadan kaynaklanıyorsa. Maalesef bu görevlerden herhangi birinin başarısını garanti edemiyorum (ağ bağlantısını kes, kontrolüm dışında olan hatalı biçimlendirilmiş JSON nesnesi).

Sonuç olarak, bir istisna ile karşılaşırsam, onu işlev içinde yakalarım ve arayan kişiye FALSE döndürürüm. Benim mantığım, arayanın gerçekten ilgilendiği tek şey, görevin başarılı olup olmadığı, neden başarılı olmadığı değil.

İşte tipik bir yöntemin bazı örnek kodları (JAVA'da))

public boolean doSomething(Object p_somthingToDoOn)
{
    boolean result = false;

    try{
        // if dirty object then clean
        doactualStuffOnObject(p_jsonObject);

        //assume success (no exception thrown)
        result = true;
    }
    catch(Exception Ex)
    {
        //don't care about exceptions
        Ex.printStackTrace();
    }
    return result;
}

Bu yaklaşımın iyi olduğunu düşünüyorum, ancak istisnaları yönetmek için en iyi uygulamaların ne olduğunu gerçekten merak ediyorum (gerçekten bir istisnayı bir çağrı yığınına kadar tüm yol boyunca şişirmeli miyim?).

Anahtar soruların özeti olarak:

  1. İstisnaları yakalamak, ancak onları şişirmek veya sistemi resmi olarak bilgilendirmek (bir günlük veya kullanıcıya bildirim yoluyla) doğru mudur?
  2. Bir dene / yakala bloğu gerektiren her şeyle sonuçlanmayan istisnalar için hangi en iyi uygulamalar var?

Takip Et / Düzenle

Tüm geri bildirimler için teşekkürler, çevrimiçi istisna yönetimiyle ilgili bazı mükemmel kaynaklar bulduk:

Görünüşe göre istisna yönetimi, bağlama göre değişen şeylerden biri. Ancak en önemlisi, bir sistem içindeki istisnaları nasıl yönettikleri konusunda tutarlı olmalıdır.

Ek olarak, aşırı deneme / yakalama yoluyla kod çürümesine dikkat edin veya bir istisnaya saygı göstermeyin (bir istisna sistemi uyarmaktır, başka ne uyarılması gerekir?).

Ayrıca, bu m3rLinEz'den güzel bir seçim yorumu .

Anders Hejlsberg'e ve sizinle aynı fikirdeyim ki, en çok arayan kişi sadece ameliyatın başarılı olup olmadığını önemsiyor.

Bu yorumdan, istisnalarla uğraşırken üzerinde düşünülmesi gereken bazı sorular ortaya çıkıyor:

  • Bu istisnanın ortaya çıktığı nokta nedir?
  • Bununla başa çıkmak nasıl mantıklı?
  • Arayan kişi istisnayı gerçekten önemsiyor mu yoksa sadece aramanın başarılı olup olmadığını mı önemsiyor?
  • Bir arayanı potansiyel bir istisnayı yönetmeye zorlamak zarif mi?
  • Dilin putlarına saygı duyuyor musunuz?
    • Boolean gibi bir başarı bayrağı döndürmeniz gerçekten gerekiyor mu? Boolean (veya int) döndürmek, Java'dan çok C zihniyetidir (Java'da sadece istisnayı halledersiniz).
    • Dille ilgili hata yönetimi yapılarını izleyin :)!

Oracle topluluğunun makalesi java dilinde olmasına rağmen, oldukça geniş bir dil sınıfı için genel bir tavsiye. Güzel makale, tam aradığım şey.
Bunny Rabbit

Yanıtlar:


61

İstisnaları yakalamak ve bunları hata kodlarına dönüştürmek istemeniz bana garip geliyor. Arayanın hata kodlarını istisnalar yerine hem Java hem de C # için varsayılan olarak tercih ettiğini düşünüyorsunuz?

Sorularınıza gelince:

  1. Yalnızca gerçekten başa çıkabileceğiniz istisnaları yakalamalısınız. Sadece istisnaları yakalamak çoğu durumda yapılacak doğru şey değildir. Birkaç istisna vardır (örneğin, iş parçacıkları arasında günlük kaydı ve sıralı istisnalar), ancak bu durumlarda bile istisnaları genel olarak yeniden atmanız gerekir.
  2. Kodunuzda kesinlikle çok fazla dene / yakala ifadesi bulunmamalıdır. Yine, fikir yalnızca başa çıkabileceğiniz istisnaları yakalamaktır. Herhangi bir işlenmemiş istisnayı son kullanıcı için bir şekilde yararlı bir şeye dönüştürmek için en üst düzey bir istisna işleyicisi ekleyebilirsiniz, ancak aksi takdirde her bir istisnayı mümkün olan her yerde yakalamaya çalışmamalısınız.

Birisinin neden istisnalar yerine hata kodları isteyeceğine gelince ... Uygulamam bir istisna oluştursa bile HTTP'nin hala hata kodları kullanmasının tuhaf olduğunu düşündüm. HTTP neden istisnayı olduğu gibi geçirmeme izin vermiyor?
Trejkaz

yapabileceğiniz en iyi şey, hata kodlarınızı bir monad içine kaydırmaktır
lindenrovio

@Trejkaz İstisna detayını kullanıcılara iade etmek istemezsiniz çünkü bu bir güvenlik riskidir. HTML sunucularının hata kodları döndürmesinin nedeni budur. Bu aynı zamanda bir hata mesajı döndürmek için bir yerelleştirme sorunudur ve muhtemelen HTML'nin boyutunu büyütür ve dönüşü yavaşlatır. Tüm bunlar, HTML sunucularının hata kodları döndürmesinin nedeni.
Didier A.

Sanırım şunu söylemenin daha iyi olacağını düşünüyorum: "Yalnızca gerçekten başa çıkabileceğiniz istisnaları bastırmalısınız."
Didier A.

@didibus Neden güvenlik endişelerinin geliştirmede bir rahatsızlık yaratması gerektiğini düşünüyorsunuz? Prodüksiyondan hiç bahsetmedim. Hata mesajı yerelleştirmesine gelince, tüm web sitesinde zaten bu sorun var ve insanlar başa çıkıyor gibi görünüyor.
Trejkaz

25

Bu, uygulamaya ve duruma bağlıdır. Bir kütüphane bileşeni oluşturuyorsanız, istisnaları oluşturmalısınız, ancak bunların bileşeninizle bağlamsal olacak şekilde sarılması gerekir. Örneğin, bir Xml Veritabanı oluşturuyorsanız ve diyelim ki verilerinizi depolamak için dosya sistemini kullanıyorsanız ve verileri korumak için dosya sistemi izinlerini kullanıyorsanız. Uygulamanızı sızdırdığı için bir FileIOAccessDenied istisnası oluşturmak istemezsiniz. Bunun yerine, istisnayı kaydırır ve bir AccessDenied hatası verirsiniz. Bu, özellikle bileşeni üçüncü şahıslara dağıtırsanız geçerlidir.

İstisnaları yutmanın bir sakıncası yokmuş gibi. Bu, sisteminize bağlıdır. Uygulamanız arıza durumlarını ele alabiliyorsa ve kullanıcıya neden başarısız olduğunu bildirmenin bir faydası yoksa, devam edin, yine de hatayı günlüğe kaydetmenizi şiddetle tavsiye ederim. Bir sorunu gidermeye yardımcı olmak için çağrılmanın ve istisnayı yuttuklarını (veya iç istisnayı ayarlamadan değiştirip yerine yenisini attıklarını) görmeyi her zaman sinir bozucu buldum.

Genel olarak aşağıdaki kuralları kullanıyorum:

  1. Bileşenlerimde ve kitaplıklarımda, yalnızca onu halletmek veya buna dayalı bir şey yapmak niyetindeysem bir istisna yakalarım. Veya bir istisna durumunda ek bağlamsal bilgi sağlamak istersem.
  2. Uygulama giriş noktasında veya mümkün olan en yüksek seviyede genel bir deneme yakalama kullanıyorum. Buraya bir istisna gelirse onu kaydeder ve başarısız olmasına izin veririm. İdeal olarak istisnalar asla buraya gelmemelidir.

Aşağıdaki kodu bir koku olarak buluyorum:

try
{
    //do something
}
catch(Exception)
{
   throw;
}

Bunun gibi kodlar hiçbir işe yaramaz ve dahil edilmemelidir.


@Josh, istisnaları yutma konusunda iyi bir nokta, ancak istisnaları yutmanın kabul edilebilir olduğu birkaç durum olduğuna inanıyorum. Son projede kod pasajınız zorunluydu, kokuyordu. Hepsini günlüğe kaydetmek daha da kötü oldu, Tavsiyem, istisnayı kaldıramıyorsanız, yutmamaya çalışın.
smaclell

Dediğim gibi bir araya getirildiğinde, bunların tümü uygulamaya ve belirli bağlama bağlıdır. Nadir olmasına rağmen istisnaları yuttuğum zamanlar vardır ve en son ne zaman yaptığımı hatırlayamıyorum ;-) Muhtemelen kendi kaydedicimi yazıyordum ve günlüğe yazma ve ikincil günlük başarısız oldu.
JoshBerke

Kod bir noktaya hizmet eder: "Fırlatma" sırasında bir kesme noktası ayarlayabilirsiniz.
Rauhotz

3
Zayıf nokta, VS'ye atılan herhangi bir istisnayı kırmasını söyleyebilir veya onu daraltabilir ve belirli bir istisna seçebilirsiniz.
VS2008'de

"Kod kokusu" örneğinin bu basit biçimde bile kesin bir yan etkisi vardır. Fırlatılan noktanın etrafında // do somethingherhangi bir try/finallyblok varsa , bloklar finallybloktan önce yürütülür catch. Olmazsa try/catchistisna, herhangi bir finallyblok çalıştırılmadan yığının en üstüne kadar uçacaktır . Bu, üst düzey işleyicinin finallyblokları çalıştırıp çalıştırmayacağına karar vermesine olanak tanır .
Daniel Earwicker

9

Konuyla ilgili başka bir iyi kaynak tavsiye etmek istiyorum. C # ve Java'nın mucitleri, sırasıyla Anders Hejlsberg ve James Gosling ile, Java'nın Kontrol Edilmiş İstisnası konusunda bir röportaj.

Arıza ve İstisnalar

Sayfanın altında da harika kaynaklar var.

Anders Hejlsberg'e ve sizinle aynı fikirdeyim ki, en çok arayan kişi sadece ameliyatın başarılı olup olmadığını önemsiyor.

Bill Venners : Kontrol edilen istisnalarla ilgili olarak ölçeklenebilirlik ve versiyonlama endişelerinden bahsettiniz. Bu iki konu ile ne kastettiğinizi açıklayabilir misiniz?

Anders Hejlsberg : Sürüm oluşturmaya başlayalım, çünkü sorunları orada görmek oldukça kolay. Diyelim ki, A, B ve C istisnalarını attığını bildiren bir foo yöntemi oluşturduğumu varsayalım. Foo'nun ikinci sürümünde, birkaç özellik eklemek istiyorum ve şimdi foo, istisna D'yi atabilir. bu yöntemin throws cümlesine D ekleyin, çünkü bu yöntemin mevcut çağırıcısı bu istisnayı neredeyse kesinlikle işlemeyecektir.

Yeni bir sürümde bir throws yan tümcesine yeni bir istisna eklemek, istemci kodunu bozar. Arayüze bir yöntem eklemek gibidir. Bir arayüz yayınladıktan sonra, tüm pratik amaçlar için değiştirilemez, çünkü herhangi bir uygulaması, bir sonraki sürüme eklemek istediğiniz yöntemlere sahip olabilir. Yani bunun yerine yeni bir arayüz oluşturmanız gerekiyor. İstisnalarla benzer şekilde, ya daha fazla istisna atan foo2 adında yepyeni bir yöntem oluşturmanız ya da yeni foo'da istisna D'yi yakalamanız ve D'yi bir A, B veya C'ye dönüştürmeniz gerekir.

Bill Venners : Ama yine de bu durumda kodlarını, istisnaları kontrol edilmemiş bir dilde bile kırmıyor musunuz? Foo'nun yeni sürümü, istemcilerin işlemeyi düşünmesi gereken yeni bir istisna atacaksa, kodları yalnızca kodu yazarken bu istisnayı beklemedikleri gerçeğiyle kırılmıyor mu?

Anders Hejlsberg : Hayır, çünkü çoğu durumda insanlar umursamıyor. Bu istisnaların hiçbiriyle ilgilenmeyecekler. Mesaj döngülerinin etrafında bir alt seviye istisna işleyicisi var. Bu işleyici, neyin yanlış gittiğini ve devam ettiğini söyleyen bir iletişim kutusu açacak. Programcılar, her yerde try nihayet yazarak kodlarını korurlar, böylece bir istisna olursa doğru şekilde geri dönerler, ancak istisnaları ele almakla aslında ilgilenmezler.

Fırlatma cümlesi, en azından Java'da uygulandığı şekilde, sizi istisnalarla başa çıkmaya zorlamaz, ancak bunlarla başa çıkmazsanız, sizi hangi istisnaların kesin olarak geçebileceğini kabul etmeye zorlar. Bildirilen istisnaları yakalamanızı veya bunları kendi atış cümlenize koymanızı gerektirir. Bu gereksinimi aşmak için insanlar saçma şeyler yapar. Örneğin, her yöntemi "atar İstisna" ile dekore ederler. Bu, özelliği tamamen ortadan kaldırır ve sen programcının daha fazla gobbledy gunk yazmasını sağladın. Bu kimseye yardımcı olmuyor.

DÜZENLEME: Dönüşümle ilgili daha fazla ayrıntı eklendi


Bunun için teşekkürler! Sorumu cevabınızla ilgili bilgilerle güncelledim!
AtariPete

Görünüşe göre Bay Hejlsberg, Pokemon istisna işlemlerini haklı çıkarıyor. Java ve C #'daki istisnaların tasarımıyla ilgili en büyük sorunlardan biri, istisna türünde çok fazla bilginin kodlanmasıdır , ancak istisna örneklerinde saklanması gereken bilgi tutarlı bir şekilde mevcut değildir. İstisnalar, burada temsil edilen tüm anormal koşullar çözülene kadar çağrı yığınını yaymalıdır; ne yazık ki, bir istisnanın türü - tanınsa bile - bir durumun çözülüp çözülmediğini göstermek için çok az şey yapar. Bir istisna tanınmazsa ...
supercat

... durum daha da kötü. Kod çağırırsa FetchDatave beklenmedik bir türden bir istisna atarsa, bu istisnanın sadece verilerin kullanılamaz olduğu anlamına gelip gelmediğini bilmesinin bir yolu yoktur (bu durumda kodun o olmadan geçme yeteneği onu "çözer") veya CPU'nun yandığını ve sistemin ilk fırsatta "güvenli kapatma" yapması gerektiği anlamına gelip gelmediği. Görünüşe göre Bay Hejlsberg kodun ilkini varsayması gerektiğini öneriyor; Belki de mevcut istisna hiyerarşileri göz önüne alındığında mümkün olan en iyi strateji budur, ancak yine de garip görünüyor.
supercat

Exceptin'in atışlarının saçma olduğuna katılıyorum, çünkü neredeyse her şey bir istisna yaratabilir, bunun olabileceğini varsaymalısınız. Ama A, B, C gibi istisnaları belirttiğinizde, bu sadece bir not, benim için bir Yorum bloğu gibi kullanılmalıdır. Bu, benim fonksiyonumun müşterisi, işte bir ipucu, belki A, B, C ile uğraşmak istersiniz, çünkü bu hataların beni kullanırken meydana gelmesi muhtemeldir. İleride D eklerseniz, o ele varlık değilse büyük bir anlaşma değil, ama şimdi o da D. yakalamak için yararlı olacağını arada Ah, yeni belgelere ekleme gibi
Didier A.

8

Kontrol edilen istisnalar genel olarak tartışmalı bir konudur ve özellikle Java'da (daha sonra lehine olanlar ve onlara karşı olanlar için bazı örnekler bulmaya çalışacağım).

Genel kural olarak, istisna işleme, belirli bir sıra olmadan bu yönergeler etrafında bir şey olmalıdır:

  • Sürdürülebilirlik uğruna, her zaman istisnaları günlüğe kaydedin, böylece hataları görmeye başladığınızda, günlük, hatanızın muhtemelen başladığı yeri göstermenize yardımcı olur. Asla ayrılmayın printStackTrace()ya da beğenmeyin, kullanıcılarınızdan biri sonunda bu yığın izlerinden birini alacak ve onunla ne yapılacağı konusunda tam olarak sıfır bilgiye sahip olacak.
  • Başa çıkabileceğiniz istisnaları ve yalnızca bunları yakalayın ve bunlarla başa çıkın, onları yığından ayırmayın.
  • Her zaman belirli bir istisna sınıfını yakalayın ve genellikle türü asla yakalamamalısınız Exception, aksi takdirde önemli istisnaları yutma olasılığınız çok yüksektir.
  • Asla (asla) yakalama Error!! Anlamına: Hiç yakalamak Throwables olarak Errors ikincisi alt sınıflarıdır. ErrorBüyük olasılıkla asla üstesinden OutOfMemorygelemeyeceğiniz sorunlardır (ör . veya diğer JVM sorunları)

Özel durumunuzla ilgili olarak, yönteminizi arayan herhangi bir istemcinin uygun dönüş değerini alacağından emin olun. Bir şey başarısız olursa, boole döndürme yöntemi yanlış döndürebilir, ancak bu yöntemi çağırdığınız yerlerin bunu işleyebildiğinden emin olun.


Kontrol edilen istisnalar, bunlara sahip olmadığı için C # 'da bir sorun değildir.
cletus

3
Imho, bazen hataları yakalamak iyidir: Yazdığım çok bellek yoğun bir Java uygulamasını hatırlıyorum. OutOfMemory-Ex'i yakaladım ve kullanıcıya hafızasının yetersiz olduğunu, diğer programlardan çıkması gerektiğini ve ona daha fazla yığın alanı atanmış jvm'yi nasıl başlatacağını anlatan bir mesaj gösterdim. Sanırım yardımcı oldu.
Lena Schimmel

5

Yalnızca başa çıkabileceğiniz istisnaları yakalamalısınız. Örneğin, bir ağ üzerinden okumakla uğraşıyorsanız ve bağlantı zaman aşımına uğrarsa ve bir istisna ile karşılaşırsanız tekrar deneyebilirsiniz. Bununla birlikte, bir ağ üzerinden okuyorsanız ve bir IndexOutOfBounds istisnası alıyorsanız, bunu gerçekten halledemezsiniz çünkü buna neyin neden olduğunu bilmiyorsunuz (bu durumda, bu durumda bilemezsiniz). Yanlış veya -1 veya null döndürecekseniz, bunun belirli istisnalar için olduğundan emin olun. Atılan istisna yığın bellek yetersiz olduğunda, bir ağ okumasında yanlış döndüren bir kitaplık istemiyorum.


3

İstisnalar, normal program yürütmenin parçası olmayan hatalardır. Programınızın ne yaptığına ve kullanımına bağlı olarak (yani bir kelime işlemciye karşı kalp monitörü) bir istisna ile karşılaştığınızda farklı şeyler yapmak isteyeceksiniz. Normal uygulamanın bir parçası olarak istisnaları kullanan kodla çalıştım ve kesinlikle bir kod kokusu.

Ör.

try
{
   sendMessage();

   if(message == success)
   {
       doStuff();
   }
   else if(message == failed)
   {
       throw;
   }
}
catch(Exception)
{
    logAndRecover();
}

Bu kod beni kusuyor. IMO, kritik bir program olmadığı sürece istisnalardan kurtulmamalısınız. İstisnalarınız varsa, o zaman kötü şeyler oluyor.


2

Yukarıdakilerin tümü makul görünmektedir ve genellikle iş yerinizin bir politikası olabilir. Bizim SystemExceptionyerimizde İstisna türlerini tanımladık: (işaretli değil) ve ApplicationException(işaretli).

E- SystemExceptionpostaların kurtarılamayacağına ve en üstte bir kez ele alınacağına karar verdik. Ayrıca bağlam sağlamak için, bizim SystemExceptionler onlar oluştuğu, örneğin belirtmek için exteneded edilir RepositoryException, ServiceEceptionvb

ApplicationExceptions gibi ticari anlamlar olabilir InsufficientFundsExceptionve müşteri kodu tarafından ele alınmalıdır.

Somut bir örnek olmakla birlikte, uygulamanız hakkında yorum yapmak zordur, ancak dönüş kodlarını asla kullanmam, bunlar bir bakım sorunudur. Bir İstisnayı yutabilirsiniz, ancak neden olduğuna karar vermeniz ve her zaman olayı ve yığın izini günlüğe kaydetmeniz gerekir. Son olarak, yönteminizin başka bir işlemi olmadığı için oldukça fazladır (kapsülleme dışında?), Dolayısıyla doactualStuffOnObject(p_jsonObject);bir boole döndürebilir!


1

Biraz düşündükten ve kodunuza baktıktan sonra, bana öyle geliyor ki, istisnayı bir boole olarak yeniden atıyorsunuz. Yöntemin bu istisnayı geçmesine izin verebilirsiniz (onu yakalamak zorunda bile değilsiniz) ve onu arayan kişide halledebilirsiniz, çünkü önemli olan yer orasıdır. İstisna, arayanın bu işlevi yeniden denemesine neden olacaksa, istisnayı yakalayan kişi olmalıdır.

Bazen karşılaştığınız istisna arayan için bir anlam ifade etmeyebilir (yani bu bir ağ istisnasıdır), bu durumda bunu bir alana özel istisnaya bağlamanız gerekir.

Öte yandan, istisna, programınızda kurtarılamaz bir hata sinyali veriyorsa (yani, bu istisnanın nihai sonucu programın sonlandırılması olacaktır), şahsen, onu yakalayarak ve bir çalışma zamanı istisnası atarak bunu açık hale getirmeyi seviyorum.


1

Örneğinizde kod modelini kullanacaksanız, onu TryDoSomething olarak adlandırın ve yalnızca belirli istisnaları yakalayın.

Ayrıca , teşhis amacıyla istisnaları günlüğe kaydederken bir İstisna Filtresi kullanmayı düşünün . VB, İstisna filtreleri için dil desteğine sahiptir. Greggm'in bloguna bağlantı, C # 'dan kullanılabilen bir uygulamaya sahiptir. İstisna filtreleri, yakalama ve yeniden atma yerine hata ayıklama için daha iyi özelliklere sahiptir. Özellikle sorunu filtreye kaydedebilir ve istisnanın yayılmaya devam etmesine izin verebilirsiniz. Bu yöntem, bir JIT (Tam Zamanında) hata ayıklayıcısının tam orijinal yığına sahip olmasını sağlar. Bir yeniden atma, desteyi yeniden atıldığı noktada keser.

TryXXXX'in mantıklı olduğu durumlar, gerçekten istisnai olmayan veya işlevi çağırmadan test etmesi zor olan durumlarda fırlatan bir üçüncü taraf işlevi sarmaladığınızda ortaya çıkar. Bir örnek şöyle bir şey olabilir:

// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse); 

bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
     try
     {
         parsedInt = ParseHexidecimal(numberToParse);
         return true;
     }
     catch(NumberNotHexidecimalException ex)
     {
         parsedInt = 0;
         return false;
     }
     catch(Exception ex)
     {
         // Implement the error policy for unexpected exceptions:
         // log a callstack, assert if a debugger is attached etc.
         LogRetailAssert(ex);
         // rethrow the exception
         // The downside is that a JIT debugger will have the next
         // line as the place that threw the exception, rather than
         // the original location further down the stack.
         throw;
         // A better practice is to use an exception filter here.
         // see the link to Exception Filter Inject above
         // http://code.msdn.microsoft.com/ExceptionFilterInjct
     }
}

TryXXX gibi bir kalıp kullanıp kullanmamanız daha çok bir stil sorusudur. Tüm istisnaları yakalamak ve yutmak sorunu bir stil sorunu değildir. Beklenmeyen istisnaların yayılmasına izin verildiğinden emin olun!


.Net'teki TryXXX modelini seviyorum.
JoshBerke

1

Kullandığınız dil için standart kitaplıktan ipuçlarınızı almanızı öneririm. C # için konuşamam ama Java'ya bakalım.

Örneğin, java.lang.reflect.Array'in statik bir setyöntemi vardır:

static void set(Object array, int index, Object value);

C yolu olurdu

static int set(Object array, int index, Object value);

... dönüş değeri bir başarı göstergesidir. Ama artık C dünyasında değilsin.

İstisnaları kucakladığınızda, hata işleme kodunuzu temel mantığınızdan uzaklaştırarak kodunuzu daha basit ve daha net hale getirdiğini görmelisiniz. Tek bir tryblokta birçok ifadeye sahip olmayı hedefleyin .

Diğerlerinin de belirttiği gibi - yakaladığınız istisna türü konusunda mümkün olduğunca spesifik olmalısınız.


bu çok geçerli bir yorum, dile ve geleneksel olarak bu tür sorunları nasıl yönettiğine karşı saygılı olun. Java dünyasına C zihniyetini getirmeyin.
AtariPete

0

Bir İstisna yakalayıp yanlış döndürecekseniz, bu çok özel bir istisna olmalıdır. Bunu yapmıyorsun, hepsini yakalıyorsun ve yanlış dönüyorsun. Bir MyCarIsOnFireException alırsam, hemen öğrenmek istiyorum! İstisnaların geri kalanı umurumda olmayabilir. Öyleyse, bazı istisnalar için (ne olduğunu daha iyi açıklayan yeni bir istisnayı yeniden atın veya yakalayıp yeniden atın) ve sadece diğerleri için yanlış olarak döndüren bir istisna işleyicisine sahip olmalısınız.

Bu, piyasaya süreceğiniz bir ürünse, bu istisnaları bir yerde kaydetmelisiniz, gelecekte işleri ayarlamanıza yardımcı olacaktır.

Düzenleme: Her şeyi bir dene / yakala ile sarmalama sorusuna gelince, cevabın evet olduğunu düşünüyorum. Kodunuzda istisnalar o kadar nadir olmalıdır ki catch bloğundaki kod o kadar nadiren çalışır ki performansa hiç çarpmaz. Bir istisna, durum makinenizin kırıldığı ve ne yapacağını bilmediği bir durum olmalıdır. En azından, o sırada ne olduğunu açıklayan ve içinde yakalanmış istisnayı yeniden düzenleyin. "DoSomeStuff () yönteminde istisna", siz tatildeyken (veya yeni bir işte) neden bozulduğunu anlamak zorunda olan kişiler için pek yararlı değildir.


Bir istisna bloğunun kurulumunun da maliyetli olduğunu unutmayın ...
devstuff

0

Stratejim:

Orijinal işlev void döndürdüyse, bool döndürmek için değiştiririm . İstisna / hata oluşursa yanlış döndür , her şey yolundaysa doğru döndür .

İşlevin bir şey döndürmesi gerekiyorsa, istisna / hata oluştuğunda boş döndür, aksi takdirde iade edilebilir öğe.

Bool yerine hatanın açıklamasını içeren bir dizge döndürülebilir.

Her durumda herhangi bir şeyi iade etmeden önce hatayı kaydedin.


0

Burada bazı mükemmel cevaplar. Eklemek isterim ki, gönderdiğiniz gibi bir şeyle sonuçlanırsanız, en azından yığın izlemeden daha fazlasını yazdırın. O sırada ne yaptığınızı söyleyin ve Ex.getMessage (), geliştiriciye bir mücadele şansı vermek için.


tamamen katılıyorum. Ben sadece Ex.printStackTrace () yaptım; yakalamada yaptığım bir şeye örnek olarak (yani yeniden fırlatmamak).
AtariPete

0

try / catch blokları, birinci (ana) setin üzerine gömülü ikinci bir mantık seti oluşturur, çünkü bunlar okunamayan, hata ayıklaması zor spagetti kodunu bulmanın harika bir yoludur.

Yine de, makul bir şekilde kullanıldıklarında, okunabilirlikte harikalar yaratıyorlar, ancak sadece iki basit kurala uymalısınız:

  • bunları kütüphane işleme sorunlarını yakalamak için düşük düzeyde (az miktarda) kullanın ve bunları ana mantıksal akışa geri aktarın. İstediğimiz hata işlemenin çoğu, verinin bir parçası olarak kodun kendisinden gelmelidir. Dönen veriler özel değilse neden özel koşullar oluşturalım?

  • Düşük seviyede yakalanmayan kodda ortaya çıkan tuhaf koşulların herhangi birini veya tamamını yönetmek için üst düzeyde büyük bir işleyici kullanın. Hatalarla ilgili faydalı bir şeyler yapın (günlükler, yeniden başlatmalar, kurtarmalar vb.).

Bu iki tür hata işleme dışında, ortadaki kodun geri kalanının tamamı serbest olmalı ve dene / yakala kodu ve hata nesnelerinden arınmış olmalıdır. Bu şekilde, nerede kullanırsanız kullanın veya onunla ne yaparsanız yapın, basit ve beklendiği gibi çalışır.

Paul.


0

Cevaba biraz geç kalmış olabilirim ancak hata işleme, zaman içinde her zaman değiştirebileceğimiz ve geliştirebileceğimiz bir şeydir. Bu konu hakkında daha fazla bir şeyler okumak isterseniz yeni bloguma bununla ilgili bir yazı yazdım. http://taoofdevelopment.wordpress.com

Mutlu kodlamalar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.