Neden denemek kullanın… Sonunda bir yakalama maddesi olmadan?


79

Programlamanın klasik yolu ile try ... catch. tryOlmadan kullanmak ne zaman uygundur catch?

Python'da aşağıdakiler yasal görünür ve mantıklı olabilir:

try:
  #do work
finally:
  #do something unconditional

Ancak, kod hiçbir catchşey yapmadı. Benzer şekilde biri Java’da şöyle olacağını düşünebilir:

try {
    //for example try to get a database connection
}
finally {
  //closeConnection(connection)
}

İyi görünüyor ve birden bire istisna türleri hakkında endişelenmeme gerek yok. Bu iyi bir uygulamasa, ne zaman iyi bir uygulama? Alternatif olarak, bunun iyi bir uygulama olmama veya yasal olmama nedenleri nelerdir? (Kaynağı derlemedim. Java için bir sözdizimi hatası olabileceğinden soruyorum. Python'un kesinlikle derlendiğini kontrol ettim.)

Karşılaştığım ilgili bir sorun şudur: Sonunda bir şeyler döndürmesi gereken işlevi / yöntemi yazmaya devam ediyorum. Bununla birlikte, ulaşılmaması ve dönüş noktası olması gereken bir yerde olabilir. Bu nedenle, yukarıdaki istisnaları ele alsam bile, hala geri dönüyorum NULLveya kodun ulaşılmaması gereken bir noktada, genellikle yöntemin / işlevin sonu olan boş bir dize dönüyorum . Kodu her zaman yeniden düzenlemeyi başardım, böylece gerekmediği için return NULLkesinlikle iyi bir uygulamadan daha az görünüyor.


4
Java'da neden return ifadesini try bloğunun sonuna koymuyorsunuz?
kevin cline

2
Bunun için üzgünüm, kesinlikle deneyin ve deneyin ... ikisi de try anahtar kelimesini kullanın, ikisi de denemenin başlaması dışında ikisi tamamen farklı yapılardır.
Pieter B

3
try/catch"programlamanın klasik yolu" değildir. Bu var , program klasik C ++ yolu C ++ uygun bir deneme / nihayet de ray içeren çirkin kesmek kullanılarak garantili tersinir durum değişikliklerini uygulamak zorunda anlamına gelir inşa yoksun çünkü. Ancak iyi OO dilleri bu sorunu yaşamaz, çünkü onlar sonunda / denemeyi sağlar. Denemek / yakalamaktan çok farklı bir amaç için kullanılır.
Mason Wheeler

3
Harici bağlantı kaynakları ile çok görüyorum. İstisnayı istiyorsunuz ancak açık bir bağlantı bırakmadığınızdan emin olmanız gerekiyor. Vb. Yakaladıysanız, bazı durumlarda yine de bir sonraki katmana tekrar atarsınız.
Rig

4
@MasonWheeler "Çirkin hack" lütfen, bir nesnenin kendi temizleme işlemine sahip olmasının neyin kötü olduğunu açıklar mısın?
Baldrickk

Yanıtlar:


146

Bu noktada ortaya çıkabilecek istisnalarla baş edip edemeyeceğinize bağlıdır.

İstisnaları yerel olarak halledebiliyorsanız yapmanız gerekir ve hatayı olabildiğince yükseltildiği yere yaklaştırmak daha iyidir.

Onları yerel olarak idare edemiyorsanız, sadece bir try / finallybloğa sahip olmak tamamen mantıklıdır - yöntemin başarılı olup olmamasına bakmaksızın yürütmeniz gereken bazı kodlar olduğunu varsayalım. (Örneğin Neil'in comment ), bir dere açılması ve daha sonra yüklenecek bir iç yöntemine o akışı geçirilerek ihtiyacınız durumlara genel mükemmel bir örneğidir try { } finally { }akışı başarı bakılmaksızın kapalı olduğundan emin olmak için nihayet cümleciği kullanarak veya okuma hatası.

Ancak, uygulamanızın elbette tamamen çökmesini istemediğiniz sürece, kodunuzun herhangi bir yerinde bir istisna işleyicisine ihtiyacınız olacak . Uygulamanızın mimarisine, tam olarak bu işleyicinin bulunduğu yere bağlıdır.


8
"ve hatayı olabildiğince büyüdüğü yere yakın olarak ele almak daha iyidir." eh, bağlıdır. Görevi kurtarabilir ve hala tamamlayabilirseniz (tabiri caizse) elbette evet. Bunu yapamazsanız, istisnanın en üst seviyeye gelmesine izin vermek daha iyi olur, olanlar ile başa çıkmak için nerede (muhtemel) kullanıcı müdahalesi gerekir.
Will

13
@will - Bu yüzden "mümkün olduğunca" ifadesini kullandım.
ChrisF

8
İyi bir cevap, ancak bir örnek ekleyeceğim: Bir akışın açılması ve bu akışın yüklenecek içsel bir yönteme geçirilmesi, akışın try { } finally { }sonunda ne olursa olsun sonuçta kapatıldığından emin olmak için nihayet cetvelden yararlanarak, ihtiyacınız olduğunda mükemmel bir örnektir / hatası.
Neil

çünkü bazen en üste gelebilecek kadar yakındır
Newtopian

"sadece bir deneme / nihayet bir bloğa sahip olmak tamamen mantıklı" diyordu. thank you @ChrisF
neal aise

36

finallyBir hata durumu (durum) oluştu olsun veya olmasın blok zaman çalıştırmak gerekir kodu için kullanılır.

Bloktaki kod finally, tryblok tamamlandıktan sonra ve yakalanan bir istisna olursa, ilgili catchblok tamamlandıktan sonra çalıştırılır . Yakında tryveya catchblokta yakalanmamış bir istisna olsa bile her zaman çalıştırılır .

finallyBlok tipik açıldı vs. kapanış dosyaları, ağ bağlantıları, kullanılan trybloğun. Bunun nedeni, dosya veya ağ bağlantısının kapalı olması, bu dosyayı veya ağ bağlantısını kullanan işlemin başarılı veya başarısız olmasıydı.

finallyBir istisna oluşturmamasını sağlamak için blokta özen gösterilmelidir . Örneğin null, vb. İçin tüm değişkenleri kontrol ettiğinizden emin olun .


8
+1: "Temizlenmesi gerekir" için aptalca. Kullanımlarının çoğu try-finallybir withifadeyle değiştirilebilir .
S.Lott

12
Çeşitli dillerin try/finallyyapı için dile özgü geliştirmeleri vardır . C # vardır using, Python vardır with, vb.
yfeldblum

5
@ yfeldblum - Nesnenin kurucusunda bir istisna olursa , yöntem blok tarafından çağrılmayacağından usingve arasındaki ince bir fark vardır . Nesnenin yapıcısı bir istisna atsa bile kodu çalıştırmanıza izin verir. try-finallyDisposeusingIDisposabletry-finally
Scott Whitlock

5
@ScottWhitlock: Bu iyi bir şey mi? Ne yapmaya çalışıyorsun, yapılandırılmamış bir nesneye bir yöntem mi çağırdın? Bu bir milyar çeşit kötü.
DeadMG

1
@DeadMG: Ayrıca bkz: stackoverflow.com/q/14830534/18192
Brian

17

Bir örnek nihayet yakalamak koşulu olmadan ... deneyin uygun (ve hatta daha vardır deyimsel ) Java kullanımı olan Lock eşzamanlı programları kilitler pakette.

  • API dokümantasyonunda nasıl açıklandığı ve haklı gösterileceği (alıntıdaki koyu yazı tipi benim):

    ... Blok yapılandırılmış kilitlemenin yokluğu, senkronize yöntem ve ifadelerle oluşan kilitlerin otomatik olarak serbest bırakılmasını ortadan kaldırır. Çoğu durumda, aşağıdaki deyim kullanılmalıdır :

     Lock l = ...;
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }

    Kilitleme ve kilit açma farklı kapsamlarda gerçekleştiğinde, kilit tutulurken yürütülen tüm kodların, gerektiğinde serbest bırakıldığından emin olmak için en sonda dene veya yakala tarafından korunmasını sağlamak için özen gösterilmelidir .


l.lock()İçeri koyabilir miyim ? try{ l.lock(); }finally{l.unlock();}
RMachnik

1
teknik olarak yapabilirsiniz. Oraya koymadım çünkü anlamsal olarak daha az mantıklı. tryBu kod parçasında kaynak erişimini kapsaması amaçlanıyor, neden bununla alakasız bir şeyle kirletiliyor
gnat

4
Yapabilirsiniz, ancak l.lock()başarısız olursa, finallyblok l.lock()içinde ise tryblok çalışmaya devam eder . Gnat'ın önerdiği gibi yaparsanız, finallyblok yalnızca kilidin alındığını bildiğimizde çalışır .
Wtrmute

12

Temel düzeyde catchve finallyiki ilgili ancak farklı problemleri çözmek:

  • catch aradığınız kodla bildirilen bir sorunu ele almak için kullanılır
  • finally Bir sorun çıksa da olmasa da, geçerli kodun oluşturduğu / değiştirdiği verileri / kaynakları temizlemek için kullanılır

Yani her ikisi de bir şekilde problemlerle (istisnalar) ilişkilidir, ancak hepsinde ortak olan budur.

Önemli bir fark olduğunu finallyblok gerekir kaynaklar yaratılmış var (kaynak sızıntıları önlemek için) ve çağrı yığını içinde farklı bir düzeyde konulamaz aynı yöntemle olmak.

catchAncak farklı bir konu: bunun için doğru yer bağlıdır aslında işleyebilir nerede istisna. Bu konuda hiçbir şey yapamayacağınız bir yerde bir istisna yakalamanın faydası yoktur, bu yüzden bazen kolayca geçmesine izin vermek daha iyidir.


2
Nitpick: "... nihayet blok, kaynakların yaratıldığı yöntemde olmalı ..." . Bu şekilde yapmak kesinlikle iyi bir fikir , çünkü kaynak sızıntısı olmadığını görmek daha kolay. Ancak, gerekli bir önkoşul değildir; yani yok zorunda bu şekilde yapmak. Kaynağı, finally(statik veya dinamik) ekli bir try ifadesinin içinden bırakabilirsiniz ... ve hala% 100 sızdırmaz olabilir.
Stephen C,

6

@ yfeldblum doğru cevabı vardır: try-nihayet bir catch ifadesi olmadan genellikle uygun bir dil yapısı ile değiştirilmelidir.

C ++ 'da RAII ve yapıcılar / yıkıcılar kullanıyor; Python'da bu bir withifadedir; ve C #, bu bir usingifadedir.

Bunlar hemen hemen her zaman daha zordur çünkü ilklendirme ve sonlandırma kodu iki yerden ziyade tek bir yerde (soyutlanmış nesne).


2
Ve Java'da ARM blokları var
MarkJ

2
Her zaman için geçerli bir seçenek olmayan, kötü tasarlanmış bir nesneyi (örneğin, C # 'da IDisposable'ı uygun şekilde uygulamayan bir nesne) olduğunu varsayalım.
yarışmacı

1
@ mootinator: Kötü tasarlanmış bir nesneyi devralır ve düzeltemez misin?
Neil G

2
Veya kapsülleme? Bah. Tabii ki evet demek istiyorum.
mootinator

4

Birçok dilde bir finallydeyim return deyiminden sonra da çalışır. Bu, şöyle bir şey yapabileceğiniz anlamına gelir:

try {
  // Do processing
  return result;
} finally {
  // Release resources
}

Hangi istisna veya düzenli iade ifadesiyle yöntemin nasıl sonlandırıldığına bakılmaksızın kaynakları serbest bırakır.

Bunun iyi ya da kötü olması tartışma için hazırdır, ancak try {} finally {}istisnaların ele alınması ile sınırlı değildir.


0

I veya bu cevap diğer dillerden programcılar Pythonistas gazabı (Ben çok Python kullanmayın olarak bilmiyorum) çağırabilir, ancak bence en fonksiyonları gerektiğini değil bir var catchblok, ideal olarak konuşan. Nedenini göstermek için, bunu 80'lerin sonunda ve 90'ların başında Turbo C ile çalışırken yapmak zorunda olduğum türdeki manuel hata kodu yayılımı ile karşılaştırmama izin verin.

Öyleyse, bir görüntüyü yüklemek üzere bir işleve sahip olduğumuzu ve kullanıcının yüklenecek görüntü dosyasını seçen bir kullanıcıya yanıt olarak böyle bir şey olduğunu varsayalım ve bu, C ve montaj ile yazılmıştır:

görüntü tanımını buraya girin

Bazı düşük seviyeli işlevleri atladım, ancak hata işleme konusunda ne gibi sorumluluklara sahip olduklarına bağlı olarak, renk kodlu farklı işlev kategorileri tanımladığımı görebiliyoruz.

Arıza ve Kurtarma Noktası

Artık fonksiyon kategorilerini yazmak hiç zor olmadı "olası başarısızlık noktaları" ( throwyani olanlar ) ve "hata kurtarma ve raporlama" fonksiyonları ( catchyani bunlar ).

Bu işlevler, istisna işlemeye başlamadan önce doğru yazmak için her zaman önemsizdi, çünkü harici bir arızaya neden olan, bellek ayırmamak gibi bir işlev, yalnızca bir NULLya 0da -1ya da ya da genel bir hata kodu ya da bunun için bir şey ayarlayabilir. Ve hata kurtarma / raporlama her zaman kolaydı, çünkü çağrı yığınının aşağısında, arızaları kurtarmanın ve rapor etmenin mantıklı olduğu bir noktaya geldiğinizde, sadece hata kodunu ve / veya mesajı alıp kullanıcıya rapor edin. Ve doğal olarak, bu hiyerarşinin yaprağında, gelecekte nasıl değiştiğine bakılmaksızın asla başarısız olamayacak bir işlev ( Convert Pixel), doğru bir şekilde (en azından hata işleme ile ilgili olarak) doğru şekilde yazmak için ölüdür.

Hata Yayılımı

Ancak, insan hata eğilimli sıkıcı fonksiyonları vardı hata prapagatör doğrudan başarısızlık ama bir yerde daha derin hiyerarşi içinde başarısız olabilir çağrılan fonksiyonlar girmek yoktu olanlar. Bu noktada, Allocate Scanlinebir başarısızlık işlemek gerekebilir mallocve daha sonra aşağı bir hata döndürür Convert Scanlines, daha sonra Convert Scanlinesbu hata için kontrol edin ve onu aşağı geçmek zorunda Decompress Imageardından, Decompress Image->Parse Imageve, Parse Image->Load Imageve Load Imagehata nihayet bildirilen kullanıcı tarafında bir komutuna .

Bu, birçok insanın hata yaptığı yerdir, çünkü hataların tam anlamıyla ele alınması söz konusu olduğunda, fonksiyonların tüm hiyerarşisi için hatayı kontrol etmek ve yok etmek sadece bir hata üreticisini alır.

Dahası, eğer hata kodları fonksiyonlar tarafından döndürülürse, kod tabanımızın% 90'ını başarı ile ilgilenen değerleri döndürme kabiliyetini kaybederiz, çünkü birçok fonksiyonun bir hata kodu döndürmek için geri dönüş değerlerini ayırması gerekir . başarısızlık .

İnsan Hatasını Azaltma: Global Hata Kodları

Peki insan hatası olasılığını nasıl azaltabiliriz? Burada bazı C programcılarının öfkesini bile çağırabilirim, ancak bence derhal bir gelişme OpenGL gibi küresel hata kodlarını kullanmak glGetError. Bu, en azından başarıya anlamlı bir ilgi değeri döndürme işlevlerini serbest bırakır. Hata kodunun bir iş parçacığına yerelleştirildiği durumlarda bu iş parçacığı güvenli ve verimli hale getirmek için yollar vardır.

Bir işlevin bir hatayla karşılaşabileceği bazı durumlar da vardır, ancak önceki bir hatanın keşfi sonucunda erken dönmeden önce biraz daha uzun süre çalışmaya devam etmesi göreceli olarak zararsızdır. Bu, her bir işlevde yapılan işlev çağrılarının% 90'ına karşı hataları kontrol etmek zorunda kalmadan böyle bir şeyin gerçekleşmesini sağlar, böylece bu kadar titiz olmadan yine de doğru hata işlemesine izin verebilir.

İnsan Hatasını Azaltma: İstisna İşleme

Bununla birlikte, yukarıdaki çözüm, manüel if error happened, return errorkod yayılımının kontrol akış yönü ile uğraşmak için hala çok sayıda fonksiyon gerektirir, manüel kod türü satır sayısını azaltmış olsa bile . Her zaman bir hatayı kontrol eden ve hemen hemen her bir hata yayma fonksiyonuna geri dönen en az bir yer olması gerektiğinden, bu durumu tamamen ortadan kaldıramazdı. Bu, istisnasızlık, günü kurtarmak için resmin üzerine geldiğinde (sorta).

Ancak buradaki istisnaların ele alınmasının değeri, manuel hata yayılımının kontrol akış yönü ile başa çıkma ihtiyacını ortadan kaldırmaktır. Bu, değerinin catchkod tabanınız boyunca bir bot dolusu blok yazmak zorunda kalmamaya bağlı olduğu anlamına gelir . Yukarıdaki diyagramda, bir catchbloğa sahip olması gereken tek yer Load Image User Command, hatanın rapor edildiği yerdir. Başka hiçbir şey ideal olarak bir catchşey yapmak zorunda değildir, çünkü aksi halde hata kodu işleme kadar sıkıcı ve hataya açık hale gelmeye başlar.

Öyleyse, bana sorarsanız, istisnai durumdan zarif bir şekilde faydalanmayı gerçekten sağlayan bir kod temeli varsa, minimumcatch blok sayısına sahip olmalıdır (en azından sıfırı kastetmiyorum, fakat her benzersiz yüksek değer için bir tane gibi). başarısız olabilecek son kullanıcı işlemi ve tüm üst düzey kullanıcı işlemlerinin merkezi bir komut sistemi aracılığıyla başlatılması durumunda muhtemelen daha da az).

Kaynak Temizleme

Bununla birlikte, istisnaların ele alınması yalnızca, normal uygulama akışlarından ayrı istisnai yollarda hata yayılımının kontrol akışı yönleriyle manuel olarak uğraşmaktan kaçınma ihtiyacını çözer. Genelde hata yayıcısı olarak işlev gören bir işlev, bunu şimdi otomatik olarak EH ile yapsa bile, imha etmesi gereken bazı kaynakları edinmeye devam edebilir. Örneğin, böyle bir işlev, ne olursa olsun, işlevden dönmeden önce kapatması gereken geçici bir dosyayı açabilir veya ne olursa olsun kilidini açmak için gereken bir muteksi kilitleyebilir.

Bunun için her türlü dilden birçok programcının gazabını çağırabilirim, ancak C ++ yaklaşımının ideal olduğunu düşünüyorum. Dil , bir nesnenin kapsam dışına çıktığı anda belirleyici bir biçimde çağrılan yıkıcıları tanıtır . Bu nedenle, bir mutex'i bir imha edici ile kapsamlaştırılmış bir mutex nesnesi üzerinden kilitleyen bir C ++ kodu, manuel olarak kilidini açmaya gerek duymaz, çünkü ne olursa olsun nesne kapsam dışına çıktığında otomatik olarak açılacaktır (bir istisna olsa bile) ) karşılaştı. Bu nedenle, yerel kaynak temizliği ile uğraşmak zorunda kalmadan iyi yazılmış C ++ kodlarına gerçekten gerek yok.

Yıkıcı olmayan dillerde, finallyyerel kaynakları el ile temizlemek için bir blok kullanmaları gerekebilir . Bununla birlikte , hilkat garibesi yerindeki bütün istisnalar dışında olmak kaydıyla , kodunuzu manuel hata yayma ile değiştirmek zorunda kalmaya devam ediyor catch.

Dış Yan Etkileri Tersine Çevirme

Bu çözülmesi en güç kavramsal sorunu. Herhangi bir işlev, bir hata oluşturucu ya da başarısızlık noktası olsun, dış yan etkilere neden olursa, o zaman sistemi geri almak yerine, bir işlem yerine bir daha gerçekleşmemiş gibi bir duruma geri döndürmek için bu yan etkileri geri almak ya da "geri almak" gerekir. yarı geçerli "işlemin yarı yarıya başarılı olduğu durum". Değişmezlik ve kalıcı veri yapıları etrafında dönen işlevsel diller gibi, çoğu fonksiyonun ilk başta dış yan etkilere neden olma ihtiyacını azaltan diller dışında, bu kavramsal sorunu çok kolaylaştıran diller olmadığını biliyorum.

İşte finallysık sık mantık bu tip belirli bir işleve çok özeldir ve "kaynak temizleme kavramına çok iyi eşleşmiyor çünkü tartışmasız orada değişebilirlik ve yan etkileri etrafında döner dilde sorununa en zarif çözümleri arasında yer alıyor ". Ayrıca finally, bu durumlarda, bir catchbloğun gerekip gerekmediğine bakılmaksızın, fonksiyonunuzun onu destekleyen dillerde yan etkileri tersine çevirdiğinden emin olmak için liberal bir şekilde kullanmanızı öneririm (ve yine, eğer bana sorarsanız, iyi yazılmış kodun catchbloklar ve tüm catchbloklar yukarıdaki diyagramdaki gibi en anlamlı olduğu yerlerde olmalıdır Load Image User Command).

Hayal Dili

Bununla birlikte, IMO finallyyan etkilerin tersine çevrilmesi için idealdir ancak tam olarak değil. booleanErken çıkış durumunda (atılmış bir istisnadan veya başka şekilde) yan etkileri etkili bir şekilde geri almak için bir değişkeni tanımlamamız gerekir , şöyle ki:

bool finished = false;
try
{
    // Cause external side effects.
    ...

    // Indicate that all the external side effects were
    // made successfully.
    finished = true; 
}
finally
{
    // If the function prematurely exited before finishing
    // causing all of its side effects, whether as a result of
    // an early 'return' statement or an exception, undo the
    // side effects.
    if (!finished)
    {
        // Undo side effects.
        ...
    }
}

Eğer bir dil tasarlayabilseydim, bu problemi çözme hayalimdeki yol yukarıdaki kodu otomatikleştirmek gibidir:

transaction
{
    // Cause external side effects.
    ...
}
rollback
{
    // This block is only executed if the above 'transaction'
    // block didn't reach its end, either as a result of a premature
    // 'return' or an exception.

    // Undo side effects.
    ...
}

... yerel kaynakların temizlenmesini otomatikleştiren yıkıcılarla birlikte, sadece ihtiyacımız transactionolan şeyi yapıyoruz ( rollbackve catchyine finallyde, kendilerini temizlemeyen C kaynaklarıyla çalışmak için hala eklemek isteyebilirim ). Bununla birlikte, finallybir booleandeğişkenle şu ana kadar rüya dilimden yoksun bulduğum şeyi basitleştiren en yakın şey budur. Bunun için bulduğum en basit ikinci çözüm, C ++ ve D gibi dillerdeki kapsam koruyucularıdır , ancak “kaynak temizleme” ve “yan etkilerin tersine çevrilmesi” fikrini bulanıklaştırdığı için kapsam korumalarını her zaman biraz garip buldum. Bence bunlar farklı bir şekilde ele alınması gereken çok farklı fikirler.

Benim küçük bir dil hayalim de, değişmezlik ve kalıcı veri yapıları etrafında yoğun bir şekilde dönüp, gerekli olmasa da, büyük veri yapılarını bütünüyle derinlemesine kopyalamak zorunda kalmayan, verimli fonksiyonlar yazmasına neden oluyor. yan efektleri olmayan.

Sonuç

Her neyse, başım ağrıyorken, try/finallyPython'un yıkıcıların C ++ eşdeğeri olmadığını göz önüne alarak soketi kapatma kodunuzun gayet iyi ve harika olduğunu düşünüyorum ve şahsen bunu yan etkilerini tersine çevirmesi gereken yerler için liberal olarak kullanmanız gerektiğini düşünüyorum. ve catchen anlamlı olduğu yerlere gitmek zorunda olduğunuz yer sayısını en aza indirin .


-66

Hataları / istisnayı yakalamak ve bunları düzgün bir şekilde ele almak zorunlu değildir.

Bunu söylememin nedeni, her geliştiricinin başvurusunun davranışını bilmesi ve üstesinden gelmesi gerektiğine inanıyorum çünkü işini usulüne uygun şekilde tamamlamamış. Bir try-finally bloğunun try-catch-finally bloğunun yerine geçtiği bir durum yoktur.

Size basit bir örnek vereceğim: İstisnaları yakalamadan sunucuya dosya yükleme kodunu yazdığınızı varsayalım. Şimdi, eğer bir nedenden dolayı yükleme başarısız olursa, müşteri neyin yanlış gittiğini asla bilemez. Ancak, istisnayı yakaladıysanız, neyin yanlış gittiğini ve kullanıcının nasıl düzeltebileceğini açıklayan düzgün bir hata mesajı görüntüleyebilirsiniz.

Altın kural: Her zaman istisna yakalayın, çünkü tahmin zaman alır


22
-1: Java'da kaynakları serbest bırakmak için nihayet bir cümle gerekebilir (örneğin bir dosyayı kapatın veya bir DB bağlantısını bırakın). Bu bir istisna işleme yeteneğinden bağımsızdır.
kevin cline

@kevincline, Sonunda kullanıp kullanmamayı sormuyor ... Tek istediği bir istisna yakalamanın gerekip gerekmediği ... Denemeyi, yakalanmayı ve nihayet ne yaptığını biliyor… Sonunda en önemli kısım, hepimiz bunu ve neden kullanıldığını biliyoruz ....
Pankaj Upadhyay

63
@Pankaj: Cevabınız bir catchyan tümcesinde bir yan tümcesinde bulunması gerektiğini göstermektedir try. Ben de dahil olmak üzere daha deneyimli katılımcılar bunun kötü bir tavsiye olduğuna inanıyor. Sebepleriniz hatalı. İçeren yöntem trydurum yakalandı edilebilir tek olası yer değildir. Kod boyunca yakalama yan tümcelerini çoğaltmak yerine, en üst düzeyden yakalama ve raporlama istisnalarına izin vermek çoğu zaman en basittir ve en iyisidir.
Kevin Cline

@kevincline, başkaları hakkındaki sorunun algılanmasının biraz farklı olduğuna inanıyorum. Soru tam olarak, bir istisna yakalamalı mıyız yoksa olmaz mıydı…. Mutabakat işlemleri sadece deneme-sonunda değil, sayısız yolla yapılabilir. Ancak bu OP'nin endişesi değildi. Bir istisna oluşturmak sizin ve diğer çocuklar için yeterince iyi ise, o zaman iyi şanslar dilemeliyim.
Pankaj Upadhyay

İstisnalarla, ifadelerin normal yürütülmesinin kesintiye uğramasını istiyorsunuz (ve her adımda başarıyı manuel olarak kontrol etmeden). Bu, özellikle derinlemesine iç içe geçmiş yöntem çağrıları için geçerli olan bir durumdur - bazı kitaplıkların içindeki bir 4 yöntemi yalnızca bir istisnayı "yutamaz"; tüm katmanlardan geri atılması gerekiyor. Tabii ki, her katman bir istisnayı sarabilir ve ek bilgi ekleyebilir; Bu genellikle çeşitli nedenlerle yapılmaz, gelişmek için ek süre ve en büyük ikisi olmak üzere gereksiz ayrıntılarda bulunmazsınız.
Daniel B
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.