"Yakalamadan" "sonunda dene" yapmak mantıklı mı?


127

Bunun gibi bir kod gördüm:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

Bir tryolması gerektiğini sanıyordum catch?

Bu kod neden bu şekilde yapıyor?


1
özellikle dosya tanıtıcıları fopenveya DB bağlantısı için (ayrıca PHP'de) belirtilen diğer yanıtlar gibi temizlemeyi sağlar
MediaVince

Yanıtlar:


182

Halihazırda yürütülen yöntemin, kaynakların uygun şekilde temizlenmesine izin verirken yine de istisna atmasını istiyorsanız bu yararlıdır. Aşağıda, bir arama yönteminden gelen istisnayı ele almanın somut bir örneği verilmiştir.

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}

17
yaygın olarak aşağıdaki gibi kilitlerle kullanılır: lock.lock (); deneyin {/ * kilitli * /} sonunda {lock.unlock ()}
dk.

Sonunda içeriye bir istisna atılırsa ne olur?
barth

1
@barth Herhangi bir catchblok olmadığında , atılan finallyistisna, trybloktaki herhangi bir istisnadan önce yürütülür . Yani iki istisna bir varsa tryve bir finallybirdir atılacaktır tek istisna finally. Bu davranış PHP ve Python'da aynı değildir, çünkü her iki istisna da bu dillerde aynı anda fırlatılır ve istisna sırası tryönce bir sonra olur finally.
Yağmur

72

Orada çünkü programcı db.cleanup(), try bloğunun içindeki kod bir istisna atsa bile bunun çağrıldığından emin olmak istedi . Herhangi bir istisna bu blok tarafından ele alınmayacaktır, ancak bunlar yalnızca son blok yürütüldükten sonra yukarı doğru yayılacaktır.


23
+1 Kesinlikle. tryİzin vermek sadece orada finally. İstisnalar yakalanmaz.
zockman

2
+1, istisnanın yakalanana kadar yığında devam ettiğini netleştirmek için. Teşekkürler
Kod Jokey

20

Bu kod neden bu şekilde yapıyor?

Çünkü görünüşe göre kod bu seviyedeki istisnaları nasıl ele alacağını bilmiyor. Sorun değil - arayanlardan biri yaptığı sürece, yani istisna sonuçta bir yerde ele alındığı sürece.

Çoğu zaman, düşük seviyeli kod istisnalara uygun şekilde tepki veremez çünkü kullanıcının bilgilendirilmesi gerekir veya istisnanın günlüğe kaydedilmesi gerekir veya başka bir stratejinin denenmesi gerekir. Düşük seviyeli kod yalnızca bir işlevi yerine getirir ve üst düzey karar verme hakkında bilgi sahibi değildir.

Ancak kodun yine de kaynaklarını temizlemesi gerekir (çünkü yapmazsa, sızarlar), bu yüzden finallycümlecikte tam da bunu yapar , bir istisna atılsa da atılmasa da her zaman gerçekleşmesini sağlar.


2

Nihai blok, bir RuntimeException oluştuğunda (belki de çağrılan koddaki bazı hatalardan dolayı) db.cleanup()çağrının yapılmasını sağlar.

Bu aynı zamanda çok fazla iç içe geçmeyi önlemek için de kullanılır:

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

Özellikle yöntemin geri döndüğü birçok nokta olduğunda, bu okunabilirliği artırır, çünkü herkes her durumda temizleme kodunun çağrıldığını görebilir.


0

Kod, veritabanının kapatıldığından emin olmak için yapıyor.
Genellikle, bunu yapmanın yolu, tüm veritabanınızı erişim kodunu try bloğuna koymak ve ardından veritabanını kapatmak için bir çağrı yapmaktır.
Try ... nihayet çalışma şekli, try bloğundaki kodun çalıştırıldığı ve final bloğundaki kodun ne olursa olsun bittiğinde çalıştırıldığı anlamına gelir.
Bilgisayarın duvardan çekilmesinden kısa süre sonra, sonunda çalıştırılacaktır.
Bu, bir istisna çağrılsa ve yöntemin yürütülmesi üç yıl sürse bile, yine de nihayet bloğuna gireceği ve veritabanının kapatılacağı anlamına gelir.


0

Try bloğundaki kodlardan herhangi biri kontrol edilen bir istisna atabilirse, bu, yöntem imzasının atma yan tümcesinde görünmesi gerekir. Denetlenmemiş bir istisna atılırsa, yöntemden dışarı çıkar.

Nihai blok, bir istisna atılsa da atılmasa da her zaman yürütülür.

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.