문제

이 코드를 수 있습니다 절대적으로 확인finally 블록 항상 실행,no matter what something() 입니까?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}
도움이 되었습니까?

해결책

finally 될 것이라는 후 실행 trycatch 코드 블록입니다.

만 시간 finally 지 않을 것이라는습니다:

  1. 를 호출하는 경우 System.exit()
  2. 는 경우 JVM 충돌 최초
  3. 는 경우 JVM 에 도달하면 무한 루프(또는 다른 비 interruptable,종료되지 않는 문)에 trycatch
  4. 경 OS 강제 종료 JVM 프로세스예를 들어, kill -9 <pid> UNIX
  5. 면 호스트 시스템이 교만 때문이었습니다.예를들면,전원 장애,하드웨어 오류,OS 공포,등등
  6. 는 경우 finally 블록고 실행할 수 있는 데몬 스레드가 아닌 다른 모든 데몬 스레드를 종료하기 전에 finally

다른 팁

예제 코드:

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

도 있지만,그것은 나쁜 연습이 있는 경우에 반환 문에서 마지막으로 차단할 것,트럼프 다른 돌에서 일반 블록입니다.는,다음과 같은 블록 return false:

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

와 같은 일을 던지는 예외에서 마지막으로 차단합니다.

여기에서의 공식적인 단어에서 Java 언어한다.

14.20.2.실행하도-마지막으로 하려고 캐치-마지막으로

A try 문과 finally 구획에 의해 실행된 첫 번째 실행 try 니다.그런 다음 선택이있다:

  • 는 경우 실행 try 블록이 완료된 일반적으로[...]
  • 는 경우 실행 try 블록이 완료되면 갑자기기 throw 의 값 V, [...]
  • 는 경우 실행 try 블록이 완료되면 갑자기 다른 어떤 이유 R, 다음 finally 블록이 실행됩니다.그런 다음 선택이있다:
    • 는 경우 마지막으로 차단 일반적으로 완료되면,다음 try 문이 완료되면 갑자기를 위한 이유 R.
    • 는 경우 finally 블록이 완료되면 갑자기를 위한 이유 S, 다음 try 문이 완료되면 갑자기를 위한 이유 S (그 이유 R).

사양 return 실제로 이 명시적인:

JLS14.17return 문의

ReturnStatement:
     return Expression(opt) ;

A return 문 없 Expression 제어를 전송하는 호출자의 방법 또는 생성자를 포함하는니다.

A return 문과 Expression 제어를 전송하는 호출자의 방법이 포함된다;의 가치 Expression 가치가 되는 방법의 호출을 기반으로 합니다.

앞의 설명은"말 를 전송하 제어"보다는 오히려 그냥"전송 제어"때문이 있는 경우 try 문내법 또는 생성자 try 블록을 포함 return 문 다음 finally 의 조항들 try 문의 실행되기 위해서는,가장 안쪽에 있는 가장 바깥쪽,제어하기 전에 전송하는 호출자의 방법이 있습니다.갑작스러운 완료 finally 절을 중단 시킬 수 있는의 전송을 제어에 의해 시작 return 문입니다.

외에는 다른 응답,그것은 중요하다는 점을 지적한'마지막으로'권리를 재정의 예외가/반환되는 값에 의해오고 있습니다.예를 들어,다음 코드를 반환 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();
    }
}

가 위의 예와 약간의 수정

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 밖으로 실행됩니다.

후 실행 finallytry 블록 2 를 반환하고,오히려 반환 12,기 때문에 이 반환 문이 실행되지 않습니 다.

는 경우 디버그에서 이 코드 Eclipse 그럼 당신은 느낌을 얻을 후 실행 System.outfinallyreturn 문의 try 블록을 다시 실행.그러나 이것은 아닙니다.그것은 단순히 값을 반환합니다 2.

여기에는 정교 케빈의 응답.는 것이 중요하다는 표현을 반환되는 평가기 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

는 전체적인 아이디어에서 직접 사용할 수는 없습니다.그것은 당신을 당신은 정리될 수 있는 건너뛰기 때문에,돌려보내는 다른 것들 사이에서,물론입니다.

마지막으로 호출됩 무슨 일이 관계 없이 try 블록에서( 당신이 전화 System.exit(int) 또 Java 가상 머신을 맞이 다른 이유로).

논리적인 생각하는 방법에 대해 이것은:

  1. 코드 위치에서 마지막으로 차단 실행해야 합니다 무엇이든 발생하는 에서도 블록
  2. 그렇다면 코드에도록하려고 하는 값을 반환 또는 예외의 항목 위치한'선반에'때까 마지막으로 차단할 수 있는 실행
  3. 때문에 코드에서 마지막으로 블록가(에 의해 정의)우선 순위가 높은 반환할 수 있습니다 또는 어떤것이 좋아한다.어떤 경우에는 아무것도 왼쪽'선반에'는 폐기됩니다.
  4. 유일한 예외가 이 경우에는 VM 이 완전히 종료하는 동안에도록 예를 들어해'시스템이다.출구'

또한 반환에서 마지막으로는 것 던져 버리는 어떤 예외는 아니다. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

마지막으로 이용되지 않는 한 이상이 있 프로그램 종료(음 호출하면 시스템입니다.exit(0)..).그래서,당신의 sysout 을 얻을 것이 인쇄

마지막으로 차단되지 않는 한 이상이 있 프로그램을 종료,하나의 결과로서 JVM 충돌 또는 전화 System.exit(0).

의 상단에는,어떤에서 반환하는 값에서 마지막으로 블록을 재정의 반환되는 값은 실행되기 전에 마지막으로 블록,그래서 조심을 확인하는 모든 종료할 때 사용하려고 마지막으로.

No,항상 중 하나는 예외 경우// 시스템입니다.exit(0);하기 전에 마지막으로 차단을 방지하 마지막으로 실행할 수 있습니다.

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

마지막으로 항상을 실행하는지,그냥에 나타나기 때문에 코드를 반환하지 않는 것을 의미하는 방법은 구현했습니다.자바 런타임이 있는 책임에 이 코드를 실행하면 종료 try 니다.

예를 들어 있는 경우 다음과 같다:

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

런타임이 생성이 같은 것:

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

는 경우에는 잡히지 않는 예외가 발생합 finally 블록 실행 및 예외를 계속 전파.

이 때문에 할당한 값으로 12 하지 않았다,그러나의 값을 반환하는 함수.올바른 코드는 다음과 같습니다:

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

기 때문에 마지막으로 블록 항상 호출됩니다면 당신은 전화 System.exit() (또는 스레드가 충돌하).

대답은 간단하다 .

입력:

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

네,그것을 얻을 것이라고합니다.는 전체의 마지막 키워드를 사용합니다.는 경우 밖으로 뛰려고/을 잡을 차단할 수 있 건너 뛰고 마지막으로 블록이었다으로 동일을 넣어 시스템입니다.니다.system.out.println 외부 try/잡을 수 있습니다.

간결하게,공식 Java 문서(클릭 ),기록된 것-

는 경우 JVM 종료 하는 동안 시 또는 코드는 실행되는,다음 마지막으로 차단하지 않을 수 있습니다 실행합니다.마찬가지로,스레드 실행 try 또는 코드가 중단되거나 사망,마지막으로 차단할 수 있습 을 실행하지 않더라도 전체적으로 응용 프로그램이 계속됩니다.

예,마지막으로 블록가 항상 수행한다.대부분의 개발자 블록을 사용 닫는 데이터베이스 연결,resultset 체,문 개체고도 사용합으로 java 최대 절전 모드를 롤백하는 트랜잭션이 있습니다.

네,그것은 것입니다.무슨 일에 시도하거나 차단하지 않는 한 그렇지 않으면 시스템입니다.exit()호출되거나 JVM 추락했다.이 있는 경우에 반환 문서 블록(s),마지막으로 실행되기 전에 반환하는 문입니다.

네 그것은 것입니다.용 케이스하지 않는 JVM 가 종료되거나 충돌

다음 사항을 고려 프로그램:

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

으로 자바의 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.
    }
}

는 사실에 모든 언어로 항상을 실행하기 전에 반환 상관없이 반환하는 것은 방법에 있어서 몸입니다.하지 않으면 경우,마지막으로 차단 없는 많은 의미입니다.

finally 를 실행하고 그에 대한 확실합니다.

finally 를 실행하지 않습니다 아래의 경우:

case1:

실행하는 경우 System.exit().

사례 2:

을 때의 JVM/스레드에 충돌.

case3:

을 때 실행은 중지에서 간 수 있습니다.

지 않을 경우 예외 처리,종료하기 전에 프로그램,JVM 실행 마지막으로 차단합니다.그것이 실행되지 않는 경우에만 정상적으로 실행하는 프로그램의 실패를 의미의 종단의 프로그램으로 인해 다음과 같은 이유로 이러한..

  1. 에 의해를 일으키는 치명적인 오류가 원인이 되는 프로세스를 중단합니다.

  2. 종료 프로그램의 메모리로 인해 손상되었습니다.

  3. 에 의해 호출하면 시스템입니다.exit()

  4. 는 경우가 프로그램으로 무한 루프입니다.

그렇기 때문에, no 제어문 을 방지할 수 있습 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
    }
}

try- catch- finally 은 핵심 단어에 대한 예외 처리를 사용하여 경우입니다.
으로 정상적인 explanotory

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
}

마지막으로 차단을 방지 실행하면...

  • 출할 때 System.exit(0);
  • 는 경우 JVM 종료됩니다.
  • 오류는 JVM 에서

@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 

내가 이것을 시도하고, 그것은 하나의 스레드입니다.

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

Main 스레드에있을 것 기다려 주는 영원히,따라서 마지막으로 없을 것이라고,

그래서 콘솔 출력이 인쇄되지 않는 문자열: after wait()finally

동@스티븐 C,위의 예제의 경우 3 급 :

좀 더 추가하는 등 무한 루프의 가능성에 다음과 같은 코드:

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

출력:이 인쇄되지 않는다"마지막으로"의미"마지막으로 차단"에서"데몬 스레드"를 실행하지 않았

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top