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


2382

이 코드를 고려할 때 블록이 무엇이든 항상 블록이 실행 된다는 것을 절대 확신 할 수 있습니까?finallysomething()

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

473
그렇지 않은 경우 키워드의 이름을 probably대신 지정해야합니다 .
정오 실크



2
효과적인 자바는 다르게 말한다 informit.com/articles/article.aspx?p=1216151&seqNum=7
Binoy 바부

27
@BinoyBabu, 종결 자 ! = finally; finalizer == finalize()방법.
jaco0646

답변:


2697

예 . 또는 코드 블록을 finally실행 한 후에 호출됩니다 .trycatch

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

  1. 당신이 호출하면 System.exit()
  2. 당신이 호출하면 Runtime.getRuntime().halt(exitStatus)
  3. JVM이 먼저 충돌하는 경우
  4. JVM이 try또는 catch블록 에서 무한 루프 (또는 인터럽트 할 수없고 종료되지 않는 다른 명령문)에 도달 한 경우
  5. OS가 JVM 프로세스를 강제 종료하는 경우 예를 들어, kill -9 <pid>UNIX에서
  6. 호스트 시스템이 죽으면; 예 : 정전, 하드웨어 오류, OS 패닉 등
  7. 경우 finally이전 블록은 데몬 스레드와 모든 다른 비 데몬 스레드 종료에 의해 실행되는 것입니다 finally라고

44
실제로 블록이 실행되는 thread.stop()것을 반드시 막지는 않습니다 finally.
Piotr Findeisen 2016 년

181
우리는 어떻게 말에 대해 finally블록이 호출됩니다 try 블록, 그리고 전에 제어는 다음과 같은 문장으로 전달합니다. 그것은 무한 루프를 포함하는 try 블록과 일치하므로 finally 블록은 실제로 호출되지 않습니다.
Andrzej Doyle

9
중첩 된 try-catch-finally 블록을 사용할 때 또 다른 경우가 있습니다
ruhungry

7
또한, 데몬 스레드에 의해 예외가 발생하면 finally 블록이 호출되지 않습니다.
Amrish Pandey

14
@BinoyBabu-최종 블록에 관한 것이지 최종 차단에 관한 것
avmohan

567

예제 코드 :

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

18
참고 : C #에서 finally-clause 의 명령문을 대체 할 수 없다는 사실 return 2;(컴파일러 오류) 과 는 별도로 동작이 동일합니다 .
Alexander Pacha

15
알아 두어야 할 중요한 세부 사항은 다음과 같습니다. stackoverflow.com/a/20363941/2684342
WoodenKitty

18
finally 블록 자체에 return 문을 추가하여 이전 반환 값을 재정의 할 수도 있습니다. 또한 처리되지 않은 예외를 마술처럼 버립니다. 이때 코드 리팩토링을 고려해야합니다.
Zyl

8
그렇다고해서 마침내 돌아온다는 것을 증명하지는 못한다. 반환 값은 호출자 코드에서 인쇄됩니다. 많이 증명되지 않는 것 같습니다.
Trimtab 2016 년

20
죄송합니다. 이것은 증명이 아닌 데모입니다. 이 예제가 모든 Java 플랫폼에서 항상이 방식으로 작동하고 유사한 예제도 항상이 방식으로 작동 함을 보여줄 수 있다는 증거입니다.
Stephen C

391

또한 나쁜 습관이지만 finally 블록 내에 return 문이 있으면 일반 블록에서 다른 반환 값보다 우선합니다. 즉, 다음 블록은 false를 반환합니다.

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

finally 블록에서 예외를 던지는 것과 같습니다.


95
이것은 정말 나쁜 습관입니다. 왜 나쁜지에 대한 자세한 내용은 stackoverflow.com/questions/48088/… 를 참조하십시오 .
John Meagher

23
동의했다. finally {} 내의 리턴은 try {}에서 발생한 모든 예외를 무시합니다. 무서운!
neu242

8
@ dominicbri7 왜 이것이 더 나은 방법이라고 생각합니까? 함수 / 메소드가 무효 인 경우 왜 달라야합니까?
corsiKa

8
같은 이유로 저는 C ++ 코드에서 goto를 사용하지 않습니다. 여러 번 반환하면 읽기가 어렵고 디버깅하기가 더 어렵다고 생각합니다 (물론 간단한 경우에는 적용되지 않습니다). 나는 그것이
개인적으로 우호적

16
나는 특별한 경우가 발생했을 때 많은 수익을 얻는 경향이 있습니다. if (계속하지 않는 이유가 있습니다) return;
iHearGeoff

257

다음은 Java 언어 사양의 공식 단어입니다.

14.20.2. try-finally 및 try-catch-finally의 실행

블록이 있는 try명령문은 먼저 finally블록을 실행하여 실행됩니다 try. 그런 다음 선택이 있습니다.

  • try블록의 실행이 정상적으로 완료되면 [...]
  • V로try 인해 블록의 실행이 갑자기 완료되면 [...]throw
  • 실행의 경우 try블록이 다른 이유에 대해 급격 완료 R , 다음 finally블록이 실행된다. 그런 다음 선택이 있습니다.
    • finally 블록이 정상적으로 try완료되면 이유 R 로 인해 명령문이 갑자기 완료 됩니다.
    • 상기 중간 finally블록이 이유에 대해 급격 완료 Stry갑자기 이유에 대한 문이 완료 S ( 이성 R은 폐기된다 ).

에 대한 사양은 return실제로 이것을 명시 적으로 만듭니다.

JLS 14.17 반환 진술

ReturnStatement:
     return Expression(opt) ;

return아니오 문 Expression 시도 를 포함하는 방법 또는 생성자의 호출자로 제어를 전송합니다.

return와 문 Expression 시도 를 포함하는 방법의 호출자에 제어를 전송하는; 의 값은 Expression메소드 호출의 값이됩니다.

위의 설명은 "말을 시도 전송 제어에 그냥"보다는 " 전송 제어 어떤이있는 경우 때문에" try방법 또는 그 생성자 내에서 문 try블록이 포함되어 return문이 후 모든 finally사람들의 조항 try문은 바깥 쪽을 안쪽 순서대로 실행됩니다 제어가 메소드 또는 생성자의 호출자에게 전송되기 전에 finally절이 갑자기 완료되면 return명령문에 의해 시작된 제어의 전송이 중단 될 수 있습니다 .


163

다른 응답 외에도 'finally'는 try..catch 블록에 의해 예외 / 반환 된 값을 무시할 권리가 있음을 지적하는 것이 중요합니다. 예를 들어 다음 코드는 12를 반환합니다.

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

마찬가지로 다음 메소드는 예외를 발생시키지 않습니다.

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

다음과 같은 방법으로 처리합니다.

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

63
중간 케이스는 finally 블록 내에 return 문을 갖는 것이 절대적으로 끔찍한 이유입니다 (모든 Throwable을 숨길 수 있음).
Dimitris Andreou

2
누가 하지 않는 A가 surpressed 싶어 OutOfMemoryError? ;)
RecursiveExceptionException

나는 그것을 테스트했고 그런 오류를 억제하지 않는다 (그렇습니다!). 컴파일 할 때 경고를 생성합니다 (예!). 그리고 당신은 사용 후 반환 변수를 정의하고하여 해결할 수 있습니다 return retVal finally 물론 그 코드가, 그렇지 않으면 이해가되지 않기 때문에 당신이 다른 예외를 억제한다고 가정하더라도, 블록.
Maarten Bodewes

120

위의 예제를 약간 수정하여 시도했습니다.

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

이는 when return i;가 실행될 때 i값이 2 이기 때문입니다 .이 후에 finally12가 할당 된 i다음 System.outout이 실행되는 블록 이 실행됩니다.

finally블록을 실행 한 후이 try리턴 문이 다시 실행되지 않으므로 블록은 12를 반환하지 않고 2를 반환합니다.

이클립스에서이 코드를 디버깅 할 경우에 당신은 실행 후하는 느낌을 얻을 것이다 System.outfinally블록 return의 문 try블록을 다시 실행합니다. 그러나 이것은 사실이 아닙니다. 단순히 값 2를 반환합니다.


10
이 예제는 훌륭합니다. 마침내 수십 개의 관련 스레드에서 언급되지 않은 것을 추가합니다. 나는 거의 모든 개발자가 이것을 알 것이라고 생각합니다.
희망적으로 도움이 된

4
i프리미티브가 아니라 Integer 객체 인 경우 어떻게됩니까?
Yamcha

이 사례를 이해하는 데 어려움을 겪고 있습니다. docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17 은 다음과 같이 말합니다. "표현식이 포함 된 return 문은 컨트롤을 포함하는 메서드 또는 람다 본문의 호출자에게 제어를 전송하려고합니다. it .... Expression의 평가가 정상적으로 완료되면 V 값이 생성됩니다. "이 문장에서 추측 할 수있는 것은 return V는 V 값을 평가 한 후에는 표현식을 다시 평가하지 않는 것 같습니다. 반환 값에 영향을 미치지 않습니다.
meexplorer

그러나 나는 이것에 관한 어떤 증거도 발견하지 못했다. 리턴은 식을 다시 평가하지 않는다고 언급되어있다.
meexplorer

1
@meexplorer는 약간 늦었지만 JLS 14.20.2에 설명되어 있습니다. try-finally 및 try-catch-finally의 실행 -조금 복잡함, 14.17. 반환 진술 도 읽어야합니다
user85421

117

다음은 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

8
알아야 할 중요한 사항입니다.
Aminadav Glickshtein

알아두면 좋을뿐만 아니라 의미가 있습니다. 실제로 return의 가치를 돌려주는 것이 뒤에 오는 것 같습니다 finally. 반환 값 ( printX()여기)을 계산하는 것이 여전히 그 앞에옵니다.
Albert

3 개의 "반환"포인트가 모두 포함 된 좋은 예입니다!
radistao

아니. 위의 코드 System.out.println("finally trumps return... sort of");System.out.print("finally trumps return in try"); return 42;
Pacerier

54

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

마지막으로 try 블록에서 발생하는 상황관계없이 호출 됩니다 ( 다른 이유로 호출 하거나 Java Virtual Machine이 시작 되지 않는 한System.exit(int) ).


그것은 매우 약한 대답입니다. stackoverflow.com/a/65049/715269
Gangnus

42

이것을 생각하는 논리적 방법은 다음과 같습니다.

  1. finally 블록에 배치 된 코드 는 try 블록 내에서 발생 하는 모든 것을 실행해야합니다.
  2. 따라서 try 블록의 코드가 값을 반환하거나 예외를 throw하려고하면 finally 블록이 실행될 수있을 때까지 항목이 '선반'에 배치됩니다
  3. finally 블록의 코드는 정의에 따라 우선 순위가 높기 때문에 원하는 것을 반환하거나 던질 수 있습니다. 이 경우 '선반'에 남은 것은 버립니다.
  4. 이에 대한 유일한 예외는 try 블록 동안 VM이 완전히 종료 된 경우입니다 (예 : 'System.exit').

10
이것은 단지 "생각하는 논리적 방법"입니까, 아니면 finally 블록이 사양에 따라 작동하는 방식입니까? 여기서는 Sun 자원에 대한 링크가 매우 흥미로울 것입니다.
matias

21

System.exit (0) .. 호출과 같은 비정상적인 프로그램 종료가 없으면 마지막으로 항상 실행됩니다. 따라서 sysout이 인쇄됩니다



18

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

또한 finally 블록 내에서 반환 된 모든 값은 finally 블록을 실행하기 전에 반환 된 값보다 우선하므로 try finally를 사용할 때 모든 종료점을주의해서 확인하십시오.


18

항상 예외는 아닙니다 .// 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");
        }
    }
}

이것이 바로 System.exit ()를 호출해서는 안되는 이유 중 하나입니다.
Franz D.

13

마지막으로 항상 실행해야합니다. 반환 후 코드에 표시된다고해서 그것이 구현 된 방식을 의미하는 것은 아닙니다. Java 런타임은 try블록을 종료 할 때이 코드를 실행해야합니다 .

예를 들어 다음과 같은 경우

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

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

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

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


11

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

finally 블록은 호출하지 않으면 System.exit()(또는 스레드가 충돌 하지 않는 한) 항상 호출 됩니다.


10

간결하게 공식 Java 문서 ( 여기를 클릭 하십시오 )에서 다음과 같이 쓰여 있습니다.

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


10

대답은 간단하다 YES .

입력:

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

1
대답은 간단합니다.
Christophe Roussy

1
@ChristopheRoussy 어떻게? 설명해 주시겠습니까?
만나기

1
수락 된 답변을 읽으십시오. 원래 질문은 '항상 실행됩니까?'에 관한 것이며 항상 그렇지는 않습니다. 귀하의 경우 원래 질문에 대한 답변이 아니며 초보자를 오도하는 것일 수도 있습니다.
Christophe Roussy

그렇다면 어떤 경우에는 실행되지 않습니까?
만나

다른 답변에 언급 된 모든 경우에 1000 개 이상의 공감 수가있는 수락 된 답변을 참조하십시오.
Christophe Roussy

9

그렇습니다. 그것이 finally 키워드를 갖는 요점입니다. try / catch 블록을 뛰어 넘어 finally 블록을 건너 뛸 수 있다면 System.out.println을 try / catch 외부에 두는 것과 같습니다.


9

예, 마지막으로 블록은 항상 실행됩니다. 대부분의 개발자는이 블록을 사용하여 데이터베이스 연결, 결과 세트 오브젝트, 명령문 오브젝트를 닫고 트랜잭션을 롤백하기 위해 java 최대 절전 모드로 사용합니다.


9

항상

Java 언어 사양 방법에 대해 설명합니다 try- catch- finallytry- catch블록에서 작동 14.20.2
가되도록 지정없고 대신에 finally블록이 항상 실행됩니다. 그러나 모든 경우에있는이 try- catch- finallytry- finally블록이 완료되기 전에 지정 않습니다 완료 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는 다음 실행 FIN은 항상 후 실행됩니다 CODE 와 전에 다음 .

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

따라서 블록이 완료된 finally후에 항상 실행되는 블록에 따라 올바르게 동작하는 소프트웨어 try는 모두 버그가 있습니다.

returntry블록의 지침은 이 문제와 관련이 없습니다. 실행이 후 코드에 도달하면 try- catch- finally보장되는 finally블록으로 사용하거나 사용하지 않고, 이전에 실행 된 것입니다 return내부 지침 try블록.


8

그렇습니다. System.exit ()가 호출되거나 JVM이 충돌하지 않는 한 try 또는 catch 블록에서 어떤 일이 발생하더라도. 블록에 return 문이 있으면 해당 return 문 이전에 마지막으로 실행됩니다.


8

그렇습니다. JVM 종료 또는 충돌이 아닌 경우에만


8

다른 답변이 없기 때문에 @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 

Java 1.8.162부터는 이것이 출력이 아닙니다.
Sam

8

나는 이것을 시도했다, 그것은 단일 스레드입니다.

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

main Thread에있을 것입니다 wait, 영원히 상태에 따라서 finally호출되지 않을 것이다 ,

그래서 콘솔 출력은 print String: wait()또는finally

@Stephen C와 함께 위의 예는 여기 에서 세 번째 사례 중 하나입니다 .

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

// import java.util.concurrent.Semaphore;

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 ignored) {
    } finally {
        System.out.println("finally");
    }
}

사례 2 : JVM이 먼저 충돌하는 경우

import sun.misc.Unsafe;
import java.lang.reflect.Field;

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

참고 : JVM을 어떻게 중단합니까?

사례 6 : 이전 finally에 데몬 Thread과 데몬이 아닌 다른 모든 Threads종료에 의해 블록이 실행되는 경우 finally가 호출됩니다.

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

출력 : "데몬 스레드"의 "최종 블록"이 실행되지 않았 음을 의미하는 "최종"으로 인쇄되지 않습니다.

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

4
허용 된 답변을 참조하십시오. 이것은 "무한 루프"의 가장 중요한 사례입니다.
Stephen C

8

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

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

그것은해야하지 sb.setLength(0)마침내?
user7294900

sb.setLength (0)은 StringBuffer에서 데이터를 비 웁니다. 따라서 sb = null은 객체를 참조에서 분리합니다.
Sam

"xyz"가 출력에서 ​​두 번 인쇄되어서는 안됩니까? 함수가 두 번 호출되었으므로 "최종"이 한 번만 발생한 이유는 무엇입니까?
fresko

2
이것은 좋은 습관이 아닙니다. 마지막으로 sb = null;불필요한 코드 만 추가 하여 차단 합니다. 나는 당신이 finally블록이 데이터베이스 연결이나 그와 같은 자원을 자유롭게하기에 좋은 장소 라는 것을 이해 하지만, 당신의 예는 새로운 사람들을 혼란스럽게 할 수 있음을 명심하십시오.
Roc Boronat

1
@Samim 감사합니다, 나는 라인을 추가했고 System.out.println("---AGAIN2---"); System.out.println(sb);지금은 더 명확합니다. 그대로, 결과는 당신의 논문에 대한 것이 었습니다 : p 나는 또한 당신의 답변에 추가되었지만, 편집자는 중재자 또는 그와 같은 누군가에 의해 수락되어야합니다. 그렇지 않으면 추가 할 수 있습니다
fresko

7

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


7

try 블록에서 리턴을 최종적으로 대체 할 때의 리턴에 대한 점 외에 예외도 마찬가지입니다. 예외를 던지는 finally 블록은 try 블록 내에서 발생한 반환 또는 예외를 대체합니다.


7

finally 실행되고 확실합니다.

finally 다음과 같은 경우에는 실행되지 않습니다.

사례 1 :

당신이 실행할 때 System.exit().

사례 2 :

JVM / 스레드 충돌시

사례 3 :

실행이 수동으로 중지 된 경우


6
  1. 마지막으로 블록은 항상 실행됩니다. System.exit () 까지 문은이 (finally 블록의 첫 번째 문)이 존재한다.
  2. 경우 System.exit와 ()는 다음 finally 블록이 finally 블록에서 나올 실행 및 제어되지 않습니다 첫 번째 문이다. System.exit () 문이 finally 블록에 도달 할 때마다 해당 문이 마지막으로 실행되고 System.exit ()가 나타날 때 제어력이 finally 블록에서 완전히 나옵니다.

1
이것은 여러 번 답변되었으므로 어떤 새로운 정보가 답변에 추가됩니까?
Tom
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.