it-swarm-tr.com

Sonunda bir blok her zaman Java'da yürütülür mü?

Bu kodu göz önünde bulundurarak, kesinlikle eminim finally bloğunun her zaman çalıştığı, emin olun, something() ne olursa olsun?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}
2159
jonny five

Evet, finally veya try kod bloklarının yürütülmesinden sonra catch çağrılır.

finally öğesinin çağrılmadığı tek zaman:

  1. System.exit()'yi çağırdıysanız
  2. JVM önce kilitlenirse
  3. JVM, try veya catch bloğunda sonsuz bir döngüye (veya başka bir kesintisiz, sonlandırıcı olmayan ifadeye) ulaşırsa
  4. İşletim sistemi zorla JVM işlemini sonlandırırsa; örneğin, UNIX’de kill -9 <pid>
  5. Ana sistem ölürse; örneğin, elektrik kesintisi, donanım hatası, işletim sistemi panik, vb.
  6. finally bloğu bir daemon iş parçacığı tarafından yürütülecekse ve finally çağrılmadan önce diğer tüm daemon dışı konular çıkacaksa
2415
jodonnell

Örnek kod:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("finally trumps return.");
    }
}

Çıktı:

finally trumps return. 
0
502
Kevin

Ayrıca, her ne kadar kötü bir uygulama olsa da, nihayet bloğun içinde bir return ifadesi varsa, normal bloğun diğer herhangi bir getirisini atar. Başka bir deyişle, aşağıdaki satır yanlış döndürür:

try { return true; } finally { return false; }

Son bloktaki istisnaları atmakla aynı şey.

362
MooBob42

İşte Java Dil Belirtiminin resmi kelimeleri.

14.20.2. Try-finally ve try-catch-finally işlemlerinin yapılması

try bloğu olan bir finally ifadesi, önce try bloğunu yürüterek gerçekleştirilir. O zaman bir seçim var:

  • try bloğunun çalışması normal olarak tamamlanırsa, [...]
  • try bloğunun yürütülmesi, bir değerin throw değeri nedeniyle aniden tamamlanırsa V, [...]
  • try bloğunun yürütülmesi başka bir nedenden dolayı aniden tamamlanırsa R, finally bloğu çalıştırılır. O zaman bir seçenek var:
    • Son blok normalde tamamlanırsa, try ifadesi, reason R nedeniyle aniden tamamlanır.
    • finally bloğu, S nedeniyle aniden tamamlanırsa, try ifadesi, gerekçe olarak aniden tamamlanır S ( ve nedeni R atılır ).

return için şartname aslında bu açık yapar:

JLS 14.17 İade Beyanı

ReturnStatement:
     return Expression(opt) ;

return içermeyen bir Expression deyimi, kontrolü içeren yöntemi veya yapıcıyı denetleyiciye aktarmayı dener .

return içeren bir Expression ifadesi, kontrolü içeren onu içeren yönteme davet edene aktarmayı dener ; Expression değeri, yöntem çağrısının değeri olur.

Yukarıdaki açıklamalara göre " kontrolü transfer etmeye çalışır " yerine "" transferleri kontrol "try blokları try ifadesini içeren yöntem veya yapıcı içinde herhangi bir return ifadesi varsa, bu durumda, bu finally ifadelerinin try cümleleri, en başta, en önce kontrol yönteminin çağrıcısına aktarılmadan önce yürütülecektir. veya yapıcı. finally yan tümcesinin aniden tamamlanması, return deyimi tarafından başlatılan denetimin aktarılmasını engelleyebilir.

251

Diğer yanıtlara ek olarak, 'sonunda' herhangi bir istisna/döndürülen değeri try..catch bloğuyla geçersiz kılma hakkına sahip olduğunu belirtmek önemlidir. Örneğin, aşağıdaki kod 12 döndürür:

public static int getMonthsInYear() {
    try {
        return 10;
    }
    finally {
        return 12;
    }
}

Benzer şekilde, aşağıdaki yöntem bir istisna atmaz:

public static int getMonthsInYear() {
    try {
        throw new RuntimeException();
    }
    finally {
        return 12;
    }
}

Aşağıdaki yöntem onu ​​atıyor olsa da:

public static int getMonthsInYear() {
    try {
        return 12;          
    }
    finally {
        throw new RuntimeException();
    }
}
148
Eyal Schneider

Yukarıdaki örneği hafif bir değişiklikle denedim.

public static void main(final String[] args) {
    System.out.println(test());
}

public static int test() {
    int i = 0;
    try {
        i = 2;
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
    }
}

Yukarıdaki kod çıktıları:

nihayet geri dönüş kozları.
2

Bunun nedeni return i; çalıştırıldığında i öğesinin 2 değeri olmasıdır. Bundan sonra finally bloğu çalıştırılır, burada 12 i öğesine atanır ve ardından System.out çıkışı çalıştırılır.

finally bloğunu yürüttükten sonra try bloğu, 12 döndürmek yerine 2 döndürür, çünkü bu return ifadesi tekrar yürütülmez.

Bu kodu Eclipse'de hata ayıklayacaksanız, finally bloğunun System.out komutunu çalıştırdıktan sonra return bloğunun try ifadesinin yeniden yürütüldüğünü hissedeceksiniz. Ancak bu durum böyle değil. Sadece 2 değerini döndürür.

109
vibhash

İşte Kevin'in cevabı 'nin bir detaylandırması. Döndürülecek ifadenin, sonradan döndürülse bile finally öğesinden önce değerlendirildiğini bilmek önemlidir.

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int printX() {
    System.out.println("X");
    return 0;
}

public static int test() {
    try {
        return printX();
    }
    finally {
        System.out.println("finally trumps return... sort of");
    }
}

Çıktı:

X
finally trumps return... sort of
0
95
WoodenKitty

Sonunda bir blok tüm fikri budur. Elbette, diğer şeylerin yanı sıra geri döndüğünüz için, atlanabilecek temizleme işlemleri yaptığınızdan emin olmanızı sağlar.

Sonunda try bloğunda ne olursa olsun ne olursa olsun (süreceSystem.exit(int) diyorsunuz ya da Java Virtual Machine başka bir nedenden ötürü çıkıyor).

52
Chris Cooper

Bunu düşünmenin mantıklı bir yolu:

  1. Bir nihayet bloğa yerleştirilen kod çalıştırılmalıdır ne olursa olsun try bloğunun içinde
  2. Bu nedenle, try bloğundaki kod bir değer döndürmeye veya bir istisna atmaya çalışırsa, son blok çalışana kadar öğe 'rafa' yerleştirilir
  3. Son bloktaki kod (tanım gereği) yüksek önceliğe sahip olduğundan, ne isterse geri döndürebilir veya atabilir. Bu durumda 'rafta' kalan her şey atılır.
  4. Bunun tek istisnası, deneme bloğu sırasında VM tamamen kapanması, örn. 'System.exit' tarafından
38
Garth Gilmour

sonunda anormal program sonlandırma olmadıkça (System.exit (0) .. çağırıyor gibi) yürütülür. yani, sysout'unuz yazdırılacak

18
shyam

Ayrıca nihayet bir geri dönüş, herhangi bir istisnayı ortadan kaldıracaktır. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

18

Nihayet blok, bir JVM kilitlenmesinden veya bir çağrıdan System.exit(0) işlevinden kaynaklanan bir program sonlandırması olmadıkça her zaman gerçekleştirilir.

Bunun üzerine, nihayet bloğun içinden döndürülen herhangi bir değer, nihayet bloğun yürütülmesinden önce döndürülen değeri geçersiz kılar; bu nedenle, nihayet deneme kullanırken tüm çıkış noktalarını kontrol etmeye dikkat edin.

17
user9189

Hayır, her zaman bir istisna olayı olmaz // System.exit (0); nihayet bloktan önce nihayet yürütülmesini engeller.

  class A {
    public static void main(String args[]){
        DataInputStream cin = new DataInputStream(System.in);
        try{
            int i=Integer.parseInt(cin.readLine());
        }catch(ArithmeticException e){
        }catch(Exception e){
           System.exit(0);//Program terminates before executing finally block
        }finally{
            System.out.println("Won't be executed");
            System.out.println("No error");
        }
    }
}
17
Rajendra Jadi

Sonunda her zaman tam mesele budur, sadece dönüşün ardından kodda göründüğü için, bunun nasıl uygulandığı anlamına gelmez. Java çalışma zamanı try bloğundan çıkarken bu kodu çalıştırma sorumluluğuna sahiptir.

Örneğin, aşağıdakilere sahipseniz:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

Çalışma zamanı şöyle bir şey üretecektir:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

Yakalanmamış bir istisna atılırsa, finally bloğu çalışır ve istisna yayılmaya devam eder.

12
Motti

Bunun nedeni, i değerini 12 olarak atadınız, ancak i değerini işleve döndürmediniz. Doğru kod aşağıdaki gibidir:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}
10
Wasim

Çünkü nihayet bir blok, System.exit() (ya da threadın çöktüğü) çağrılmadıkça her zaman çağrılır.

9
Jay Riggs

Cevap basitEVET.

GİRİŞ:

try{
    int divideByZeroException = 5 / 0;
} catch (Exception e){
    System.out.println("catch");
    return;    // also tried with break; in switch-case, got same output
} finally {
    System.out.println("finally");
}

ÇIKTI:

catch
finally
9
Meet

Evet çağrılacak. Sonunda bir anahtar kelimeye sahip olmanın asıl amacı budur. Eğer try/catch bloğundan atlamak, nihayet bloktan atlayabiliyorsa, System.out.println'yi try/catch'in dışına koymakla aynıydı.

8
Mendelt

Evet, nihayet blok her zaman yürütülür. Geliştiricinin çoğu bu bloğu, veri tabanı bağlantısını, resultset nesnesini, ifade nesnesini kapatarak kullanır ve ayrıca işlemi geri almak için Java hazırda bekletme modunda kullanır.

8
Gautam Viradiya

Kısaca, resmi Java Dokümantasyonunda (Tıkla burada ), yazdığı -

JVM, try veya catch kodu yürütülürken çıkarsa, son blok çalıştırılmayabilir. Benzer şekilde, try veya catch kodunu yürüten iş parçacığı kesintiye uğradığında veya öldürülürse, uygulama bir bütün olarak devam etse de, sonuçta blok işleyemeyebilir.

8
bikz05

Evet olacak. JVM'nin çıkması veya çökmesi yaşanmaması gereken tek durum

7
abhig

Evet, olacak. Aksi takdirde, System.exit () denen veya JVM kilitlenmediği sürece, deneyin veya catch bloğunuzda ne olursa olsun. Bloklarda herhangi bir return ifadesi varsa, nihayet bu return ifadesinden önce yürütülecektir.

7
Karthikeyan

Aşağıdaki programı göz önünde bulundurun:

public class SomeTest {

    private static StringBuilder sb = new StringBuilder();

    public static void main(String args[]) {

        System.out.println(someString());
        System.out.println("---AGAIN---");
        System.out.println(someString());
        System.out.println("---PRINT THE RESULT---");
        System.out.println(sb.toString());
    }

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

Java 1.8.162'den itibaren, yukarıdaki kod bloğu aşağıdaki çıktıyı verir:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

bu, nesneleri serbest bırakmak için finally işlevini kullanmanın aşağıdaki kod gibi iyi bir uygulama olduğu anlamına gelir:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null; // Just an example, but you can close streams or DB connections this way.
    }
}
7
Samim

Bunu denedim, tek dişli.

class Test {
    public static void main(String args[]) throws Exception {
       Object obj = new Object();
       try {
            synchronized (obj) {
            obj.wait();
            System.out.println("after wait()");
           }
       } catch (Exception e) {
       } finally {
           System.out.println("finally");
       }
   }
}

Ana iş parçacığı sonsuza dek bekleme durumunda olacak, bu yüzden sonunda hiç aranmayacak,

bu yüzden konsol çıktısı dizeyi basmayacak: after wait() veya finally

@Stephen C ile anlaşmaya varılan yukarıdaki örnek, here 'deki 3. durumdan biridir.

Aşağıdaki kodda bu tür sonsuz döngü olanakları ekleyerek:

// import Java.util.concurrent.Semaphore;
class Test {
    public static void main(String[] args) {
        try {
            // Thread.sleep(Long.MAX_VALUE);
            // Thread.currentThread().join();
            // new Semaphore(0).acquire();
            // while (true){}
            System.out.println("after sleep join semaphore exit infinite while loop");
        } catch (Exception e) {
        } finally {
            System.out.println("finally");
        }
    }
}

Durum 2: JVM önce çökerse

import Sun.misc.Unsafe;
import Java.lang.reflect.Field;
class Test {
    public static void main(String args[]) {
        try {
            unsafeMethod();
//            Runtime.getRuntime().halt(123);
            System.out.println("After Jvm Crash!");
        } catch (Exception e) {
        } finally {
            System.out.println("finally");
        }
    }

    private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);
        unsafe.putAddress(0, 0);
    }
}

Ref: Bir JVM'yi nasıl çökertirsiniz?

Durum 6: Sonunda blok daemon thread tarafından çalıştırılacaksa ve son olarak çağrılmadan önce diğer tüm daemon non thread çıkışları.

class Test {
    public static void main(String args[]) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    printThreads("Daemon Thread printing");
                    // just to ensure this thread will live longer than main thread
                    Thread.sleep(10000);
                } catch (Exception e) {
                } finally {
                    System.out.println("finally");
                }
            }
        };
        Thread daemonThread = new Thread(runnable);
        daemonThread.setDaemon(Boolean.TRUE);
        daemonThread.setName("My Daemon Thread");
        daemonThread.start();
        printThreads("main Thread Printing");
    }

    private static synchronized void printThreads(String str) {
        System.out.println(str);
        int threadCount = 0;
        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
        for (Thread t : threadSet) {
            if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
                System.out.println("Thread :" + t + ":" + "state:" + t.getState());
                ++threadCount;
            }
        }
        System.out.println("Thread count started by Main thread:" + threadCount);
        System.out.println("-------------------------------------------------");
    }
}

Çıktı: Bu "daemon thread" da "Nihayet blok" anlamına gelen "nihayet" yazmıyor

main Thread Printing  
Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED  
Thread :Thread[main,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE   
Thread count started by Main thread:3  
-------------------------------------------------  
Daemon Thread printing  
Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE  
Thread count started by Main thread:2  
-------------------------------------------------  

Process finished with exit code 0
6
dkb

Evet, çünkü kontrol ifadesi yok , finally'nin çalıştırılmasını engelleyebilir.

İşte tüm kod bloklarının çalıştırılacağı bir referans örneği:

| x | Current result | Code 
|---|----------------|------ - - -
|   |                |     
|   |                | public static int finallyTest() {
| 3 |                |     int x = 3;
|   |                |     try {
|   |                |        try {
| 4 |                |             x++;
| 4 | return 4       |             return x;
|   |                |         } finally {
| 3 |                |             x--;
| 3 | throw          |             throw new RuntimeException("Ahh!");
|   |                |         }
|   |                |     } catch (RuntimeException e) {
| 4 | return 4       |         return ++x;
|   |                |     } finally {
| 3 |                |         x--;
|   |                |     }
|   |                | }
|   |                |
|---|----------------|------ - - -
|   | Result: 4      |

Aşağıdaki varyantta, return x; atlanacaktır. Sonuç hala 4:

public static int finallyTest() {
    int x = 3;
    try {
        try {
            x++;
            if (true) throw new RuntimeException("Ahh!");
            return x; // skipped
        } finally {
            x--;
        }
    } catch (RuntimeException e) {
        return ++x;
    } finally {
        x--;
    }
}

Tabii ki referanslar durumlarını takip eder. Bu örnek, value = 4 ile bir başvuru döndürür:

static class IntRef { public int value; }
public static IntRef finallyTest() {
    IntRef x = new IntRef();
    x.value = 3;
    try {
        return x;
    } finally {
        x.value++; // will be tracked even after return
    }
}
6
Dávid Horváth

finally yürütülür ve bu kesindir.

finally aşağıdaki durumlarda çalıştırılamaz:

dava 1 :

System.exit() komutunu çalıştırdığınızda.

durum 2:

JVM/Thread'iniz çöktüğünde.

durum 3:

Uygulamanız arasında manuel olarak durdurulduğunda.

6
Utkash Bhatt

try- catch- finally, istisna işleme durumunun kullanılmasında anahtar kelimelerdir.
Normal açıklama olarak

try {
     //code statements
     //exception thrown here
     //lines not reached if exception thrown
} catch (Exception e) {
    //lines reached only when exception is thrown
} finally {
    // always executed when the try block is exited
    //independent of an exception thrown or not
}

Son blok çalıştırmayı engelliyor ...

  • System.exit(0);'yi aradığınızda
  • JVM çıkarsa.
  • JVM'deki Hatalar
6

İstisna işlemezseniz, programı sonlandırmadan önce JVM sonunda blok uygular. Yalnızca normal programın yürütülmesi, aşağıdaki nedenlerden dolayı programın sona ermesi halinde başarısız olur.

  1. İşlemin iptal edilmesine neden olan önemli bir hataya neden olarak.

  2. Hafızanın bozulması nedeniyle programın sonlandırılması.

  3. System.exit () adlı kişiyi arayarak

  4. Program sonsuz döngüye girerse.

6

Bu aslında herhangi bir dilde doğrudur ... sonunda, geri dönüşün yöntem gövdesinde nerede olduğu fark etmeksizin, her zaman bir return ifadesinden önce yürütülür. Durum böyle olmasaydı, nihayet bloğun pek bir anlamı olmazdı.

6
Scott Dorman

@ vibhash'ın cevabına ekleme başka bir cevabın olmadığı gibi, aşağıdakine benzer bir değişken nesne durumunda ne olduğunu açıklamayın.

public static void main(String[] args) {
    System.out.println(test().toString());
}

public static StringBuffer test() {
    StringBuffer s = new StringBuffer();
    try {
        s.append("sb");
        return s;
    } finally {
        s.append("updated ");
    }
}

Çıktı olacak

sbupdated 
6

Evet, yazılmıştır buraya

JVM, try veya catch kodu yürütülürken çıkarsa, son blok çalıştırılmayabilir. Benzer şekilde, try veya catch kodunu yürüten iş parçacığı kesintiye uğradığında veya öldürülürse, uygulama bir bütün olarak devam etse de, sonuçta blok işleyemeyebilir.

5

Son olarak, try bloğundaki bir dönüşün yerine geri dönüşle ilgili noktaya ek olarak, aynısı bir istisna için de geçerlidir. Bir istisna atan bir blok, try bloğu içinden atılan bir geri dönüş veya istisnayı değiştirir.

5
Alex Miller

HER ZAMAN DEĞİL

Java Dili spesifikasyonu, try-catch-finally ve try-catch bloklarının 14.20.2 'de nasıl çalıştığını açıklar.
Hiçbir yerde, nihayet bloğun her zaman yürütüldüğünü belirtir. Ancak, try-catch-finally ve try-finally bloklarının tamamlandığı tüm durumlar için, tamamlamadan önce nihayet yürütülmesi gerektiğini belirtir.

try {
  CODE inside the try block
}
finally {
  FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).

JLS,FINkomutununKODkomutundan sonra yürütüleceğini garanti etmez. JLS,KODUveSONRAKIişleminin ardındanFINkomutunun daimaKODUişleminden sonra yürütüleceğini garanti eder. ve önceSONRAKI.

JLS neden nihayet bloğun her zaman try bloğundan sonra yürütüleceğini garanti etmiyor? Çünkü imkansız. JVM'nin, try bloğunu tamamladıktan hemen sonra ancak nihayet bloğun çalıştırılmasından önce durdurulması muhtemeldir, ancak bu mümkün değildir. JLS'nin bunu önlemek için yapabileceği hiçbir şey yok.

Bu nedenle, uygun davranışları için her zaman, blokları tamamlandıktan sonra yürütülen bloklara bağlı olan herhangi bir yazılım tıkanır.

Deneme bloğundaki döndürmeler bu sorunla ilgili değildir. Uygulama, try-catch-nihayetinden sonra koda ulaşırsa, nihayet bloğun try bloğu içinde, iadeli veya iadeli olmadan gerçekleştirilmiş olması garanti edilir.

Son blok bir kaç benzersiz senaryoda döndükten sonra çağrılmayacak: ilk önce System.exit () veya JVM çöktüğünde.

Sorunuzu en kolay şekilde yanıtlamaya çalışayım.

Kural 1 : Son blok her zaman çalışır (İstisnalar olmasına rağmen. Ama bir süre buna devam edelim.)

Kural 2 : kontrol bir deneme veya bir kilitleme bloğu bıraktığında nihayet blok satırındaki ifadelerdir. Kontrolün normal bir şekilde yürütülmesi, bir ara vermenin, devam etmenin veya devam etmenin bir sonucu olarak gerçekleşebilir. return ifadesi veya bir istisna tanıtımı.

Özel olarak bir iade ifadesi durumunda (açıklandığı zamandan beri) kontrol, çağrı yöntemini terketmek zorundadır. Bu nedenle, karşılık gelen try-finally yapısının nihayet bloğunu çağırır. Return ifadesi, son bloktan sonra yürütülür.

Son blokta bir return ifadesi olması durumunda, arama yığınını temizlediğinden beri, try bloğunda bekleyen birini kesinlikle geçersiz kılacaktır.

Burada daha iyi bir açıklamaya başvurabilirsiniz: http://msdn.Microsoft.com/en-us/ .... kavramı çoğunlukla tüm üst düzey dillerde aynıdır.

5
Sandip Solanki
  1. Sonunda Block her zaman idam edilir. Tabi ve System.exit () ifadesi bulunmadıkça (en son bloğun ilk ifadesi).
  2. Eğer system.exit () ilk ifade ise, sonunda blok çalıştırılmaz ve kontrol sonunda bloktan çıkar. Ne zaman System.exit () deyimi sonunda bu ifade nihayet blok çalıştırılana kadar nihayet bloğa girdiğinde ve System.exit () göründüğünde kontrol kuvveti tamamen nihayet bloktan dışarı çıkar.
5
Avinash Pande

Aşağıdaki kodla aynı:

static int f() {
    while (true) {
        try {
            return 1;
        } finally {
            break;
        }
    }
    return 2;
}

f 2 döndürür!

4
dibo

Çünkü final, her ne durumda olursa olsun çağrılır. İstisna yok, hala denir, istisna yakala, hala denir

4
vodkhang

Evet her zaman çağrılır, ancak bir durumda System.exit () kullanılırken çağrılmaz.

try{
//risky code
}catch(Exception e){
//exception handling code
}
finally(){
//It always execute but before this block if there is any statement like System.exit(0); then this block not execute.
}
4

Son olarak, blok her zaman istisna işlenip işlenmeyeceğini yürütür. Deneme bloğundan önce herhangi bir istisna oluştuğunda, son olarak blok çalıştırılmaz.

4
Rohit Chugh

Bir istisna atılırsa, nihayet çalışır. Bir istisna atılmazsa, nihayet çalışır. İstisna yakalanırsa, nihayet çalışır. İstisna yakalanmazsa, nihayet çalışır.

Sadece çalışmadığı zaman, JVM'den çıktığı zamandır.

4
Bhushan

Bunu normal bir yürütme sürecinde düşünün (yani, herhangi bir İstisna atılmadan): yöntem 'geçersiz' değilse, o zaman her zaman açıkça bir şey döndürür, ancak sonuçta daima yürütülür.

4
Gala101

Bu kodu deneyin, anlayacaksınız sonunda bloktaki kod return ifadesinden sonra çalıştırılır.

public class TestTryCatchFinally {
    static int x = 0;

    public static void main(String[] args){
        System.out.println(f1() );
        System.out.println(f2() );
    }

    public static int f1(){
        try{
            x = 1;
            return x;
        }finally{
            x = 2;
        }
    }

    public static int f2(){
        return x;
    }
}
4
eric2323223

Farklı forumlarda verilen tüm cevapları çok karıştırdım ve nihayet kodlamaya ve görmeye karar verdim. Çıkış:

nihayet deneme ve yakalama bloğunda geri dönüş olsa bile çalıştırılacaktır.

try {  
  System.out.println("try"); 
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} catch (Exception e) {   
  System.out.println("catch");
  return;
  //int  i =5/0;
  //System.exit(0 ) ;
} finally {  
   System.out.println("Print me FINALLY");
}

Çıktı

deneyin

Bana son olarak yazdır

  1. Eğer geri dönüşte System.exit(0) ile değiştirilirse, yukarıdaki koddaki try-catch bloğu ile herhangi bir nedenden ötürü bir istisna oluşur.
4
milton

son olarak, yuvalanmış bir son bloğun içine bir istisna atılırsa, zamanından önce çıkılabilir. Derleyici, nihayet bloğun normal olarak tamamlanmadığı veya ulaşılamayan kodunuz olduğu konusunda bir hata vereceğiniz konusunda sizi uyaracaktır. Erişilemeyen kodun hatası yalnızca atma koşullu bir ifadenin arkasında değilse veya bir döngü içinde değilse gösterilecektir.

try{
}finally{
   try{
   }finally{
      //if(someCondition) --> no error because of unreachable code
      throw new RunTimeException();
   }
   int a = 5;//unreachable code
}
3
HopefullyHelpful

Sonunda her zaman sonunda denir

denediğinizde, bir kod dener, eğer bir şey denerse, o zaman catch bu istisnayı yakalar ve bazı mssg'leri yazdırabilir veya bir hata atabilir, sonra blok çalıştırılır.

Sonunda normal olarak temizleme yapılırken kullanılır, örneğin, Java'da bir tarayıcı kullanıyorsanız, muhtemelen bir dosyayı açamamak gibi başka sorunlara yol açacağı için tarayıcıyı kapatmalısınız.

2
Rubin Luitel

son olarak, try bloğuna bir return ifadesi yerleştirseniz bile her zaman blok yürütülür. Nihai blok return ifadesinden önce çalıştırılacak.

2
Sabrina

İşte sonunda bir bloğu atlayabilen bazı koşullar:

  1. JVM, try veya catch kodu yürütülürken çıkarsa, son blok çalıştırılmayabilir. Daha fazlası Sun rehberi
  2. Normal Kapatma - bu, son Daemon olmayan iş parçacığı, Runtime.exit () ( bazı iyi bloglar ) olduğunda OR değerinden çıktığında gerçekleşir. Bir iş parçacığı çıktığında, JVM çalışan iş parçacığı bir envanter gerçekleştirir ve kalan tek iş parçacığı daemon iş parçacığı ise, düzenli bir kapatma işlemini başlatır. JVM durduğunda, kalan herhangi bir cini iş parçacığı bırakılır, sonunda bloklar çalıştırılmaz, yığınlar JVM açılmaz. Daemon thread'lar az kullanılmalıdır ve işlem yapılmadan herhangi bir zamanda güvenle bırakılabilir. Özellikle, herhangi bir G/Ç işlemi gerçekleştirebilecek görevler için arka plan iş parçacığı kullanmak tehlikelidir. Arka plan iş parçacığı en iyi zaman aşımına uğramış girdileri bellek içi önbellekten düzenli aralıklarla silen arka plan iş parçacığı gibi "Kat hizmetleri" görevleri için kaydedilir ( kaynak )

Daemon-dışı olmayan iş parçacığı örnek çıkar:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

Çıktı:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
0