Apakah masuk akal untuk melakukan "coba-akhirnya" tanpa "menangkap"?

127

Saya melihat beberapa kode seperti ini:

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

Saya pikir tryseharusnya memiliki catch?

Mengapa kode ini melakukannya seperti ini?

kelenjar
sumber
1
itu memastikan pembersihan seperti tanggapan lain yang disebutkan, terutama untuk pegangan file fopenatau koneksi DB (juga dalam PHP)
MediaVince

Jawaban:

182

Ini berguna jika Anda ingin metode yang saat ini dijalankan tetap menampilkan pengecualian sambil mengizinkan sumber daya dibersihkan dengan benar. Di bawah ini adalah contoh konkret menangani pengecualian dari metode pemanggilan.

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

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}
Taylor Leese
sumber
17
biasa digunakan dengan kunci seperti pada: lock.lock (); coba {/ * terkunci * /} akhirnya {lock.unlock ()}
menit
Apa yang terjadi jika pengecualian akhirnya dilemparkan ke dalam?
barth
1
@barth Jika tidak ada catchblok, pengecualian yang dilemparkan finallyakan dieksekusi sebelum pengecualian apa pun di tryblok tersebut. Jadi jika ada dua pengecualian, satu di dalam trydan satu di satu finally-satunya pengecualian yang akan dilempar adalah yang masuk finally. Perilaku ini tidak sama di PHP dan Python karena kedua pengecualian akan dilemparkan secara bersamaan dalam bahasa ini dan urutan pengecualiannya trypertama baru kemudian finally.
Hujan
72

Itu ada karena programmer ingin memastikan itu db.cleanup()dipanggil bahkan jika kode di dalam blok percobaan membuat pengecualian. Pengecualian apa pun tidak akan ditangani oleh blok itu, tetapi mereka hanya akan disebarkan ke atas setelah blok akhirnya dieksekusi.

Matti Virkkunen
sumber
23
+1 Tepat. Itu tryhanya untuk memungkinkan finally. Pengecualian tidak tertangkap.
zockman
2
1 untuk memperjelas bahwa pengecualian melanjutkan tumpukan hingga tertangkap. Terima kasih
Code Jockey
20

Mengapa kode ini melakukannya seperti ini?

Karena ternyata kode tidak tahu bagaimana menangani pengecualian pada level ini. Tidak apa - apa - selama salah satu pemanggil melakukannya, yaitu selama pengecualian pada akhirnya ditangani di suatu tempat.

Seringkali, kode tingkat rendah tidak dapat bereaksi dengan tepat terhadap pengecualian karena pengguna perlu diberi tahu, atau pengecualian harus dicatat, atau strategi lain harus dicoba. Kode tingkat rendah hanya menjalankan satu fungsi dan tidak tahu tentang pengambilan keputusan tingkat yang lebih tinggi.

Tetapi kode masih perlu membersihkan sumber dayanya (karena jika tidak, mereka akan bocor), jadi kode melakukan hal itu dalam finallyklausa, memastikan bahwa itu selalu terjadi, baik pengecualian dilemparkan atau tidak.

Konrad Rudolph
sumber
2

Blok terakhir memastikan bahwa meskipun RuntimeException dilemparkan (mungkin karena beberapa bug dalam kode yang dipanggil), db.cleanup()panggilan akan dilakukan.

Ini juga sering digunakan untuk mencegah terlalu banyak bersarang:

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

Terutama ketika ada banyak titik di mana metode kembali, ini meningkatkan keterbacaan karena siapa pun dapat melihat kode pembersihan dipanggil dalam setiap kasus.

FRotthowe
sumber
0

Kode melakukannya untuk memastikan bahwa database ditutup.
Biasanya, cara Anda melakukannya adalah dengan meletakkan semua kode akses database Anda di blok try, dan kemudian melakukan panggilan untuk menutup database di blok terakhir.
Cara coba ... akhirnya berfungsi, berarti kode di blok percobaan dijalankan, dan kode di blok terakhir dijalankan ketika selesai ... apa pun yang terjadi.
Setelah komputer ditarik dari dinding, akhirnya akan dijalankan.
Ini berarti bahwa meskipun pengecualian dipanggil, dan metode ini membutuhkan waktu tiga tahun untuk mengeksekusinya, itu masih akan masuk ke blok terakhir dan database akan ditutup.

chustar
sumber
0

Jika salah satu kode dalam blok percobaan dapat memunculkan pengecualian yang dicentang, kode itu harus muncul di klausa lemparan dari tanda tangan metode. Jika pengecualian yang tidak dicentang dilemparkan, itu menggelembung keluar dari metode.

Blok terakhir selalu dijalankan, baik pengecualian dilempar atau tidak.

HARGA KETIGA
sumber