이 코드를 고려할 때 블록이 무엇이든 항상 블록이 실행 된다는 것을 절대 확신 할 수 있습니까?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");
}
답변
예 . 또는 코드 블록을 finally
실행 한 후에 호출됩니다 .try
catch
finally
호출되지 않는 유일한 시간 은 다음과 같습니다.
- 당신이 호출하면
System.exit()
- 당신이 호출하면
Runtime.getRuntime().halt(exitStatus)
- JVM이 먼저 충돌하는 경우
- JVM이
try
또는catch
블록 에서 무한 루프 (또는 인터럽트 할 수없고 종료되지 않는 다른 명령문)에 도달 한 경우 - OS가 JVM 프로세스를 강제 종료하는 경우 예를 들어,
kill -9 <pid>
UNIX에서 - 호스트 시스템이 죽으면; 예 : 정전, 하드웨어 오류, OS 패닉 등
- 경우
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
답변
또한 나쁜 습관이지만 finally 블록 내에 return 문이 있으면 일반 블록에서 다른 반환 값보다 우선합니다. 즉, 다음 블록은 false를 반환합니다.
try { return true; } finally { return false; }
finally 블록에서 예외를 던지는 것과 같습니다.
답변
다음은 Java 언어 사양의 공식 단어입니다.
14.20.2. try-finally 및 try-catch-finally의 실행
블록이 있는
try
명령문은 먼저finally
블록을 실행하여 실행됩니다try
. 그런 다음 선택이 있습니다.
try
블록의 실행이 정상적으로 완료되면 […]- 값 V로
try
인해 블록의 실행이 갑자기 완료되면 […]throw
- 실행의 경우
try
블록이 다른 이유에 대해 급격 완료 R , 다음finally
블록이 실행된다. 그런 다음 선택이 있습니다.
- finally 블록이 정상적으로
try
완료되면 이유 R 로 인해 명령문이 갑자기 완료 됩니다.- 상기 중간
finally
블록이 이유에 대해 급격 완료 S 후try
갑자기 이유에 대한 문이 완료 S ( 이성 R은 폐기된다 ).
에 대한 사양은 return
실제로 이것을 명시 적으로 만듭니다.
ReturnStatement: return Expression(opt) ;
return
아니오 문Expression
시도 를 포함하는 방법 또는 생성자의 호출자로 제어를 전송합니다.
return
와 문Expression
시도 를 포함하는 방법의 호출자에 제어를 전송하는; 의 값은Expression
메소드 호출의 값이됩니다.위의 설명은 “말을 시도 전송 제어에 그냥”보다는 ” 전송 제어 어떤이있는 경우 때문에”
try
방법 또는 그 생성자 내에서 문try
블록이 포함되어return
문이 후 모든finally
사람들의 조항try
문은 바깥 쪽을 안쪽 순서대로 실행됩니다 제어가 메소드 또는 생성자의 호출자에게 전송되기 전에finally
절이 갑자기 완료되면return
명령문에 의해 시작된 제어의 전송이 중단 될 수 있습니다 .
답변
다른 응답 외에도 ‘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();
}
}
답변
위의 예제를 약간 수정하여 시도했습니다.
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 이기 때문입니다 .이 후에 finally
12가 할당 된 i
다음 System.out
out이 실행되는 블록 이 실행됩니다.
finally
블록을 실행 한 후이 try
리턴 문이 다시 실행되지 않으므로 블록은 12를 반환하지 않고 2를 반환합니다.
이클립스에서이 코드를 디버깅 할 경우에 당신은 실행 후하는 느낌을 얻을 것이다 System.out
의 finally
블록 return
의 문 try
블록을 다시 실행합니다. 그러나 이것은 사실이 아닙니다. 단순히 값 2를 반환합니다.
답변
다음은 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