it-swarm-ko.tech

Finally 블록은 항상 Java로 실행됩니까?

이 코드를 고려할 때절대적으로finally 블록이 something()에 상관없이 항상 실행된다는 것을 확신 할 수 있습니까?

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

예, finallytry 또는 catch 코드 블록을 실행 한 후에 호출됩니다.

finally이 호출되지 않는 유일한 시간은 다음과 같습니다.

  1. System.exit()을 호출하면
  2. JVM이 처음으로 충돌하는 경우
  3. JVM이 try 또는 catch 블록의 무한 루프 (또는 중단되지 않는 다른 종료 문)에 도달하면
  4. OS가 강제로 JVM 프로세스를 종료하는 경우 예 : UNIX에서 kill -9 <pid>
  5. 호스트 시스템이 종료되면; 전원 오류, 하드웨어 오류, OS 패닉 등
  6. finally 블록이 데몬 스레드에 의해 실행되고 finally이 호출되기 전에 다른 모든 비 데몬 스레드가 종료되면
2415
jodonnell

예제 코드 :

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.");
    }
}

산출:

finally trumps return. 
0
502
Kevin

또한 나쁜 실행이지만 finally 블록 내에 return 문이 있으면 일반 블록의 다른 모든 반환보다 우선합니다. 즉, 다음 블록은 false를 반환합니다.

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

Finally 블록에서 예외를 throw하는 것과 동일한 작업입니다.

362
MooBob42

다른 응답에 덧붙여서, 'finally'는 try..catch 블록에 의해 모든 예외/반환 값을 오버라이드 할 수있는 권리가 있음을 지적하는 것이 중요합니다. 예를 들어, 다음 코드는 12를 반환합니다.

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

마찬가지로, 다음 메소드는 예외를 throw하지 않습니다.

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

다음 메소드가 던져 버리는 동안 :

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

나는 약간의 변경으로 위의 예제를 시도했다.

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.");
    }
}

위 코드는 다음을 출력합니다.

마침내 돌아옵니다.
2

이것은 return i;가 실행될 때 i이 값 2를 가지기 때문입니다. finally 블록이 실행 된 후 12가 i에 할당 된 다음 System.out 출력이 실행됩니다.

finally 블록을 실행 한 후 try 블록은이 return 문이 다시 실행되지 않기 때문에 12를 반환하는 대신 2를 반환합니다.

Eclipse에서이 코드를 디버깅 할 경우 finally 블록의 System.out를 실행 한 후 return 블록의 try 문을 다시 실행한다는 느낌을 갖게됩니다. 그러나 이것은 사실이 아닙니다. 단순히 값 2를 반환합니다.

109
vibhash

여기에 Kevin의 대답 을 자세히 설명합니다. 후에 반환되는 경우에도 finally보다 먼저 반환되는식이 평가된다는 것을 알아야합니다.

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");
    }
}

산출:

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

그것이 finally 블록의 전체 아이디어입니다. 물론 다른 방법으로 돌아 오기 때문에 건너 뛸 수있는 정리를 수행 할 수 있습니다.

Try 블록에서 마지막으로 어떤 일이 있든 상관없이라고합니다. ( unless System.exit(int) 또는 Java 호출 다른 이유).

53
Chris Cooper

이것을 생각해 볼 수있는 논리적 인 방법은 다음과 같습니다.

  1. Finally 블록에 배치 된 코드는 try 블록 내에서 발생하는 모든 것 _ 실행되어야합니다.
  2. 따라서 try 블록의 코드가 값을 반환하거나 예외를 throw하려고하면 finally 블록이 실행될 때까지 항목이 '선반에 놓입니다'
  3. Finally 블록의 코드는 정의에 따라 높은 우선 순위를 가지기 때문에 원하는대로 반환하거나 throw 할 수 있습니다. 어떤 경우에 '선반에 놓아 둔'것은 버려집니다.
  4. 유일한 예외는 VM이 (가) try 블록 중에 완전히 종료 된 경우입니다. 'System.exit'에 의해
38
Garth Gilmour

마지막으로 System.exit (0) 호출과 같이 비정상적인 프로그램 종료가 발생하지 않는 한 항상 실행됩니다. 따라서, sysout이 인쇄됩니다.

18
shyam

또한 마침내 돌아와서 예외를 버릴 것입니다. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

18

Finally 블록은 JVM 충돌 또는 System.exit(0) 호출로 인해 비정상적인 프로그램 종료가 발생하지 않는 한 항상 실행됩니다.

그 중 finally 블록에서 반환 된 값은 finally 블록을 실행하기 전에 반환 된 값을 무시하므로 finally try를 사용할 때 모든 종료 점을 확인하는 데주의해야합니다.

17
user9189

아니요, 항상 하나의 예외 사례가 // System.exit (0)입니다. finally 블록이 최종적으로 실행되는 것을 막기 전에.

  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

마지막으로 항상 실행됩니다. 모든 요소가 반환 된 후에 코드에 나타나기 때문에 구현 방법을 의미하는 것은 아닙니다. Java 런타임은 try 블록을 종료 할 때이 코드를 실행할 책임이 있습니다.

예를 들어 다음과 같은 경우 :

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

런타임은 다음과 같은 것을 생성합니다 :

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

포착되지 않은 예외가 발생하면 finally 블록이 실행되고 예외가 전파됩니다.

12
Motti

이것은 i의 값을 12로 지정했지만 i의 값을 함수에 반환하지 않았기 때문입니다. 올바른 코드는 다음과 같습니다.

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

Finally 블록은 System.exit() (또는 쓰레드 충돌)을 호출하지 않는 한 항상 호출되기 때문에.

9
Jay Riggs

대답은 간단합니다.

INPUT :

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");
}

출력 :

catch
finally
9
Meet

예, 전화가 걸립니다. finally 키워드를 사용하는 것이 중요합니다. try/catch 블록에서 점프하여 finally 블록을 건너 뛸 수 있다면 System.out.println을 try/catch 외부에 둡니다.

8
Mendelt

예, 블록은 항상 실행됩니다. 대부분의 개발자는이 블록을 사용하여 데이터베이스 연결, 결과 집합 개체, 명령문 개체를 닫고 Java 하이버 네이트를 사용하여 트랜잭션을 롤백합니다.

8
Gautam Viradiya

간략하게, 공식 Java 문서 (클릭 여기 )에서 다음과 같이 쓰여 있습니다.

Try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록이 실행되지 않을 수 있습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 인터럽트되거나 죽는 경우 응용 프로그램 전체가 계속 실행 되더라도 finally 블록이 실행되지 않을 수 있습니다.

8
bikz05

예, 가능합니다. JVM 종료 또는 중단이 아닌 경우에만

7
abhig

예, 가능합니다. try 또는 catch 블록에서 System.exit ()이 호출되거나 JVM이 중단되지 않으면 아무 일도 일어나지 않습니다. 블록에 return 문이 있으면 return 문보다 먼저 실행됩니다.

7
Karthikeyan

다음 프로그램을 고려하십시오.

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 이후, 위의 코드 블록은 다음과 같은 결과를 제공합니다 :

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

이것은 finally을 사용하여 객체를 해제하는 것이 다음 코드와 같은 좋은 방법임을 의미합니다.

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

내가 이것을 시도, 그것은 단일 스레드입니다.

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");
       }
   }
}

메인 쓰레드는 영원히 대기 상태가 될 것이고, 결국에는 결코 호출되지 않을 것이다.

그래서 콘솔 출력은 문자열을 출력하지 않습니다 : after wait() 또는 finally

@Stephen C와의 합의, 위의 예는 세 번째 사례 언급 중 하나입니다. here :

다음 코드에서 이러한 무한 루프 가능성을 더 추가하십시오.

// 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");
        }
    }
}

사례 2 : JVM이 처음 충돌하는 경우

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 : JVM을 어떻게 충돌 시키나요?

사례 6 : 마침내 블록이 데몬 스레드에 의해 실행되고 다른 모든 데몬이 아닌 스레드가 마침내 호출되기 전에 종료됩니다.

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("-------------------------------------------------");
    }
}

출력 : "데몬 스레드"의 "마지막 블록"이 실행되지 않았 음을 의미하는 "finally"를 인쇄하지 않습니다.

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

예, 제어 문이 없음 finally이 실행되지 못하게 할 수 있습니다.

다음은 모든 코드 블록이 실행되는 참조 예입니다.

| 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      |

아래의 변형에서 return x;는 건너 뜁니다. 결과는 여전히 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--;
    }
}

참고 문헌은 물론 그들의 상태를 추적합니다. 이 예는 value = 4가있는 참조를 반환합니다.

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이 실행되고 그 것이 확실합니다.

finally은 다음과 같은 경우 실행되지 않습니다 :

사례 1 :

System.exit()을 (를) 실행할 때.

사례 2 :

JVM/스레드가 충돌 할 때.

사례 3 :

당신의 실행이 수동으로 중단 될 때.

6
Utkash Bhatt

try- catch- finally은 예외 처리의 주요 단어입니다.
정상적인 설명으로서

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
}

Finally 블록은 실행을 막습니다 ...

  • System.exit(0);을 (를) 호출 할 때
  • JVM이 종료 된 경우.
  • JVM의 오류
6

예외를 처리하지 않으면 프로그램을 종료하기 전에 JVM이 finally 블록을 실행합니다. 다음과 같은 이유로 프로그램의 정상적인 실행이 프로그램의 종료를 실패하는 경우에만 실행됩니다.

  1. 치명적인 오류로 인해 프로세스가 중단됩니다.

  2. 메모리 손상으로 인한 프로그램 종료.

  3. System.exit ()를 호출하면

  4. 프로그램이 무한 루프로 들어가면.

6

그것은 실제로 모든 언어에서 사실입니다. 마침내 return 문 앞에 항상 실행됩니다. return이 메서드 본문에 있어도 관계 없습니다. 그렇지 않은 경우 finally 블록은별로 의미가 없습니다.

6
Scott Dorman

@ vibhash의 답변에 추가 다른 답변은 아래의 것과 같이 변경 가능한 객체의 경우 어떻게되는지 설명합니다.

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 ");
    }
}

출력

sbupdated 
6
Pradeep Kumaresan

예, 쓰여집니다 여기

Try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록이 실행되지 않을 수 있습니다. 마찬가지로 try 또는 catch 코드를 실행하는 스레드가 인터럽트되거나 죽는 경우 응용 프로그램 전체가 계속 실행 되더라도 finally 블록이 실행되지 않을 수 있습니다.

5
Danail Tsvetanov

Try 블록의 리턴을 마지막으로 대체 할 때의 리턴에 대한 요점 이외에 예외도 마찬가지입니다. 예외를 throw하는 finally 블록은 try 블록 내에서 throw 된 반환 또는 예외를 대체합니다.

5
Alex Miller

항상 가지 말라.

Java 언어 사양은 try-catch-finally 및 try-catch 블록이 14.20.2
finally 블록이 항상 실행되도록 지정합니다. 그러나 try-catch-finally 및 try-finally 블록이 완료되는 모든 경우에 대해 완료 전에 완료되도록 지정해야합니다.

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는 CODE 뒤에 FIN가 실행된다는 것을 보장하지 않습니다. JLS는 CODENEXT가 실행되면 CODENEXT 앞에 항상 FIN ].

Finally 블록이 try 블록 후에 항상 실행되는 것을 JLS가 보증하지 않는 이유는 무엇입니까? 왜냐하면 불가능하기 때문입니다. JVM이 try 블록을 완료 한 직후이지만 finally 블록을 실행하기 전에 중단 (kill, crash, power off) 될 가능성은 거의 없습니다. JLS가 이것을 피할 수있는 방법은 없습니다.

따라서, try 블록이 완료된 후에 finally 블록이 실행될 때마다 적절한 동작을하는 모든 소프트웨어가 도청됩니다.

Try 블록의 반환 값은이 문제와 관련이 없습니다. try-catch-finally 다음에 실행이 코드에 도달하면 finally 블록이 try 블록 내에 반환되거나 반환되거나 반환되지 않을 수도 있습니다.

5

Finally 블록은 몇 가지 독특한 시나리오에서 반환 된 후에 호출되지 않습니다. System.exit ()가 먼저 호출되거나 JVM이 충돌하는 경우입니다.

가능한 가장 쉬운 방법으로 질문에 대답하도록 노력하겠습니다.

Rule 1 : finally 블록은 항상 실행됩니다 (예외가 있지만 언젠가는 이것을 고수하십시오).

Rule 2 : finally 블록의 문은 컨트롤이 try 또는 catch 블록을 벗어날 때 실행됩니다. 컨트롤의 전송은 정상 실행, 중단 실행, 계속, goto 또는 return 문의 결과로 발생할 수 있습니다 , 또는 예외 전파 (propogation).

반환 문이 명시 적으로 (자막이있는 이후부터), 컨트롤은 호출하는 메서드를 벗어나야하고, 따라서 해당 try-finally 구조체의 finally 블록을 호출합니다. return 문은 finally 블록 다음에 실행됩니다.

Finally 블록에도 return 문이있는 경우 호출 스택을 지우므로 try 블록에서 보류중인 문을 확실히 오버 라이드 (override)합니다.

http://msdn.Microsoft.com/en-us/ 개념은 모든 고급 언어에서 거의 동일합니다.

5
Sandip Solanki
  1. 마지막으로 Block은 항상 실행됩니다. System.exit () statement가 존재하지 않는 한 (finally 블록의 첫 번째 문).
  2. system.exit () 가 첫 번째 문이면 finally 블록이 실행되지 않고 finally 블록에서 제어가 나옵니다. System.exit () 문이 finally 블록에 도달 할 때까지 해당 문이 finally 블록에서 실행될 때까지 그리고 System.exit ()이 나타나는 경우 제어 도구가 finally 블록에서 완전히 나옵니다.
5
Avinash Pande

다음 코드와 동일합니다.

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

f가 2를 반환합니다!

4
dibo

결승전은 당신이 어떤 경우 에든 항상 호출되기 때문에. 당신은 예외가 없으며, 여전히 호출되어 예외를 잡아냅니다. 여전히 호출됩니다.

4
vodkhang

예, 항상 호출되지만 한 상황에서는 System.exit ()을 사용할 때 호출하지 않습니다.

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
Akash Manngroliya

마지막으로 블록은 항상 예외 처리 여부를 실행합니다. try 블록 전에 예외가 발생하면 finally 블록이 실행되지 않습니다.

4
Rohit Chugh

예외가 발생하면 마침내 실행됩니다. 예외가 throw되지 않으면 마지막으로 실행됩니다. 예외가 잡히면 마침내 실행됩니다. 예외가 포착되지 않으면 마침내 실행됩니다.

JVM이 종료 될 때까지만 실행되지 않습니다.

4
Bhushan

정상적인 실행 과정에서 이것을 고려하십시오. 즉, 예외가 throw되지 않습니다. 메서드가 'void'가 아닌 경우에는 항상 명시 적으로 무언가를 반환하지만 마침내 항상 실행됩니다.

4
Gala101

이 코드를 시도해 보면, finally 블록의 코드가 return 문 다음에 실행된다는 것을 이해할 것입니다 .

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

나는 다른 포럼에서 제공되는 모든 대답과 매우 혼동되어 마침내 코딩하고 보려고 결정했습니다. 출력은 다음과 같습니다.

try 및 catch 블록에 return이 있어도 finally가 실행됩니다.

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");
}

출력

시험

마침내 인쇄 해주세요.

  1. Try에서 return을 System.exit(0)으로 대체하고 위의 코드에서 catch 블록을 사용하면 어떤 이유로 든 예외가 발생합니다.
4
milton

중첩 된 finally 블록 내에서 예외가 throw되면 최종적으로 조기에 종료 될 수도 있습니다. 컴파일러는 finally 블록이 정상적으로 완료되지 않거나 도달 할 수없는 코드가 있다고 경고합니다. 도달 할 수없는 코드에 대한 오류는 throw가 조건문 뒤에 있거나 루프 내에있는 경우에만 표시됩니다.

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

마지막으로 항상 마침내 호출됩니다.

시도 할 때 뭔가 코드가 실행됩니다. try가 발생하면 catch가 해당 예외를 catch하고 일부 mssg를 출력하거나 오류를 throw 한 다음 finally 블록이 실행됩니다.

마지막으로 청소를 할 때 일반적으로 사용됩니다. 예를 들어 Java에서 스캐너를 사용하는 경우 일부 파일을 열 수 없거나 다른 파일을 열 수 없거나

2
Rubin Luitel

finally 블록은 return 문을 try 블록에 넣더라도 항상 실행됩니다. finally 블록은 return 문 앞에 실행됩니다.

2
Sabrina

Finally 블록을 무시할 수있는 몇 가지 조건은 다음과 같습니다.

  1. Try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록이 실행되지 않을 수 있습니다. Sun tutorial 에 대한 추가 정보
  2. 정상 종료-Runtime.exit () ( 일부 좋은 블로그 ) 일 때 데몬이 아닌 마지막 스레드가 OR를 종료 할 때 발생합니다. 스레드가 종료되면 JVM은 실행중인 스레드의 인벤토리를 수행하고 남은 스레드 만 데몬 스레드 인 경우 순차적 종료를 시작합니다. JVM이 중지되면 나머지 데몬 스레드가 모두 폐기되고 마지막으로 블록이 실행되지 않고 스택이 풀리지 않고 JVM이 종료됩니다. 데몬 스레드는 약간만 사용해야하며, 정리 작업없이 언제든지 처리 작업을 안전하게 포기할 수 있습니다. 특히, 모든 종류의 I/O를 수행 할 수있는 작업에는 데몬 스레드를 사용하는 것이 위험합니다. 데몬 스레드는 메모리 내 캐시에서 만료 된 항목을 주기적으로 제거하는 백그라운드 스레드와 같은 "가정 유지"작업을 위해 가장 잘 저장됩니다 ( source )

마지막 비 데몬 스레드 엑시트 예제 :

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.");
    }
}

산출:

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