Java Try Catch Nihayet Catch olmadan bloklar


125

Bazı yeni kodları inceliyorum. Programın yalnızca bir try ve final bloğu vardır. Catch bloğu hariç tutulduğundan, try bloğu bir istisna veya atılabilir herhangi bir şeyle karşılaşırsa nasıl çalışır? Doğrudan en sonunda bloğa mı gidiyor?



25
@mP Herkes kod incelemeleri yapmalı ve onlardan sorular sormak nasıl öğrenilip geliştirileceğidir.
Carl Pritchett

Yanıtlar:


130

Try bloğundaki kodlardan herhangi biri kontrol edilmiş bir istisna atabilirse, bu, yöntem imzasının throws cümlesinde 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.


11
İlk paragraf mutlaka doğru değildir. Deneme blokları yuvalanabilir. Kontrol edilmemiş olsun ya da olmasın yakalanmamış istisnalar, yöntemden fırlayacaktır.
Andy Thomas

4
Deneme blokları iç içe yerleştirilebilir, ancak bunu tavsiye etmem. Ben bu şekilde kod yazmam.
duffymo

2
@duffymo: "Metodun dışına çıkmış" kelimesinin anlamı nedir?
Bugün17

5
@Anand, "bir istisna atmak" için biraz teknik olmayan bir dil.
duffymo

2
Göz ardı edilmedi; yöntem zincirini geç.
duffymo

93

try/ Hakkında küçük bir not finally: Son, her zaman

  • System.exit() denir.
  • JVM çöküyor.
  • try{}Blok asla uçları (örn sonsuz döngü).

4
Peki ya try{..} catch{ throw ..} finally{..}? Sanırım sonunda idam edilmeyecek
sbeliakov

10
Bu durumda nihayet hala çağrılacak. Yalnızca orijinal istisna kaybedilir.
Peter Lawrey

Son olarak, daha önce System.exit () öğesini çağırırsanız da çalıştırılmayacaktır.
mmirror

2
@jyw Yukarıdaki listedeki ilk maddeden kastettiğim buydu.
Peter Lawrey

Söylemeliyim, bu tüm temelleri kapsıyor!
Oscar Bravo

39

Java Dil Spesifikasyonu (1) nasıl try-catch-finallyyürütüleceğini açıklar . Yakalanmamak, verilen Fırlatılabilir'i yakalayamamakla eşdeğerdir.

  • Try bloğunun yürütülmesi, bir V değerinin atılması nedeniyle aniden tamamlanırsa, bir seçim vardır:
    • V'nin çalışma zamanı türü, try ifadesinin herhangi bir catch cümlesinin parametresine atanabilirse, o zaman
      ……
    • V'nin çalışma zamanı türü try deyiminin herhangi bir catch cümlesinin parametresine atanamazsa, o zaman final bloğu çalıştırılır . O zaman bir seçim var:
      • Nihayet bloğu normal şekilde tamamlanırsa, try ifadesi V değerinin atılması nedeniyle aniden tamamlanır.
      • Nihai blok S nedeni ile aniden tamamlanırsa, o zaman try ifadesi S nedeni ile aniden tamamlanır (ve V değerinin atılması atılır ve unutulur).

(1) Try-catch-nihayet yürütme


16

İç son olarak, istisnayı dış bloğa atmadan önce yürütülür.

public class TryCatchFinally {

  public static void main(String[] args) throws Exception {

    try{
        System.out.println('A');
        try{
            System.out.println('B');
            throw new Exception("threw exception in B");
        }
        finally
        {
            System.out.println('X');
        }
        //any code here in the first try block 
        //is unreachable if an exception occurs in the second try block
    }
    catch(Exception e)
    {
        System.out.println('Y');
    }
    finally
    {
        System.out.println('Z');
    }
  }
}

Sonuçlar

A
B
X
Y
Z

6

Nihai blok, try bloğu bittikten sonra her zaman çalıştırılır, try normal veya normal bir istisna nedeniyle, er, atılabilir.

Try bloğundaki herhangi bir kod tarafından bir istisna atılırsa, o zaman geçerli yöntem aynı istisnayı yeniden atar (veya atmaya devam eder) (final bloğunu çalıştırdıktan sonra).

Nihai blok bir istisna / hata / atılabilirlik atarsa ​​ve zaten bekleyen bir atılabilir durum varsa, çirkinleşir. Açıkçası, tam olarak ne olduğunu unutuyorum (yıllar önce sertifikam için çok fazla). Ben düşünüyorum hem throwables birbirine bağlanmış olsun, ama yapmanız gereken bazı özel voodoo var (yani - Ben bakmak zorunda kalacak bir yöntem çağrısı) "nihayet" kustum, er, kustu önce orijinal sorunu olsun.

Bu arada, deneyin / nihayet kaynak yönetimi için oldukça yaygın bir şeydir, çünkü java'da yıkıcılar yoktur.

Örneğin -

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

"Sonunda", bir ipucu daha: eğer do bir catch koymak için zahmet, ya yakalama spesifik (beklenen) throwable alt sınıfları, ya da sadece yakalamak "Throwable", değil genel catch-all hata tuzak "İstisna",. Yansıma saçmalıkları gibi çok fazla sorun, "İstisnalar" yerine "Hatalar" atar ve bunlar şu şekilde kodlanmış herhangi bir "tümünü yakala" tarafından kayar:

catch ( Exception e) ...  // doesn't really catch *all*, eh?

bunun yerine şunu yapın:

catch ( Throwable t) ...

Çirkin kısım için aşağıdaki Carlos Heuberger'in cevabına bakın.
mplwork

3

Sürüm 7'den önceki Java sürümleri, bu üç deneme-yakalama kombinasyonuna izin verir ...

try - catch
try - catch - finally
try - finally

finallytryveya / ve catchblokta ne olduğuna bakılmaksızın blok her zaman yürütülecektir . yani catchblok yoksa, istisna burada ele alınmayacaktır.

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

  • Java try bloğunun ardından catch veya last block gelmelidir.
  • Her try bloğu için, sıfır veya daha fazla catch bloğu olabilir, ancak yalnızca bir nihai blok olabilir.
  • Program çıkarsa (System.exit () çağırarak veya işlemin durmasına neden olan ölümcül bir hataya neden olarak) sonuncu blok çalıştırılmayacaktır.

1
"sürüm 7 izin verilmeden önce" Java 7 ve Java 8'in bu üç bileşime izin vermediğini mi ima ediyorsunuz? Bunu kastettiğinizden şüpheliyim, ama cevabınızın ima ettiği bu.
Loduwijk

try bloğunda bir return ifadesi varsa, final bloğu yürütülüyor mu?
Rahul Yadav

@Rahul Evet, sonunda aranacak. Ref: stackoverflow.com/questions/65035/…
roottraveller

1
@Aaron - try anahtar sözcüğünden hemen sonra parantez içinde oluşturulan herhangi bir şey için otomatik olarak .close () işlevini çağıran, kaynakla dene için yeni sözdizimi.
Roboprog

2

try bloğu, bir istisna veya atılabilecek herhangi bir şeyle karşılaşırsa nasıl çalışır?

İstisna, yakalanmadığı diğer durumlarda olduğu gibi bloktan atılır.

Nihayet bloğu, try bloğundan nasıl çıkıldığına bakılmaksızın yürütülür - herhangi bir yakalama olup olmadığına bakılmaksızın, eşleşen bir yakalama olup olmadığına bakılmaksızın.

Yakalama blokları ve nihayet, try bloğunun ortogonal parçalarıdır. İkisinden birine veya ikisine birden sahip olabilirsiniz. Java 7 ile ikisine de sahip olamayacaksınız!


1

O programla denemiyor musun? Sonunda nihayet bloğu engelleyecek ve yürütecek, ancak istisna ele alınmayacak. Ancak, bu istisna, nihayet blokta reddedilebilir!


1

Son blok, try bloğu tamamlandıktan sonra yürütülür. Try bloğunun içine bir şey çıktığında atılırsa, nihayet bloğu çalıştırılır.


0

İç trybloğa bir istisna atabilecek kodlar yazıyoruz. catchİstisnayı işlemeyi nerede bloktur. finallyBlok olursa olsun her zaman istisna olsun veya olmasın, yürütülür.

Şimdi, dene-yakala-nihayet bloğu yerine dene-nihayet bloğumuz varsa, o zaman istisna ele alınmayacak ve bloğu yakalamak yerine kontrol bloğundan sonra blok nihayet bloğa gidecek. İstisna ile hiçbir şey yapmak istemediğimizde try-final bloğunu kullanabiliriz.


0

tryBlokta atılan veya atılmayan istisnalara bakılmaksızın - finallyblok çalıştırılacaktır. İstisna yakalanmaz.

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.