이 코드를 고려하면절대적으로 확실한그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()
;try
또는catch
블록;thread.stop()
반드시 예방하지는 않는다.finally
실행을 차단하십시오. - Piotr Findeisenfinally
블록이 호출됩니다.후그만큼try
블록 및전에제어는 다음 명령문으로 전달됩니다. 그것은 무한 루프를 포함하는 try 블록과 일관되게 결국 finally 블록이 실제로 호출되지 않는다는 것과 일치합니다. - Andrzej Doyle
예제 코드 :
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 2;
허용되지 않습니다 (컴파일러 오류). - Alexander Pacha
또한 나쁜 실행이지만 finally 블록 내에 return 문이 있으면 일반 블록의 다른 모든 반환보다 우선합니다. 즉, 다음 블록은 false를 반환합니다.
try { return true; } finally { return false; }
finally 블록에서 예외를 던지는 것과 같은 일입니다.
다음은 Java 언어 사양의 공식 단어입니다.
14.20.2. try-finally 및 try-catch-finally 실행
에이
try
성명서finally
블록은 먼저try
블록. 그런 다음 선택이 있습니다.
- 실행의 경우
try
블록이 정상적으로 완료되면 [...]- 실행의 경우
try
블록은 갑자기throw
값의V, [...]- 실행의 경우
try
다른 이유로 블록이 갑자기 완료됩니다.아르 자형, 그 다음에finally
블록이 실행됩니다. 그런 다음 선택이 있습니다.
- finally 블록이 정상적으로 완료되면
try
이유문으로 진술이 갑자기 완료된다.아르 자형.- 만약
finally
블록이 이유 때문에 갑자기 완료된다.에스, 그 다음에try
이유문으로 진술이 갑자기 완료된다.에스(이유아르 자형버려진).
에 대한 사양return
사실이 사실을 명시 적으로 나타냅니다.
ReturnStatement: return Expression(opt) ;
에이
return
성명서가없는 성명서Expression
시도컨트롤을 포함하는 메서드 또는 생성자의 호출자에게 제어권을 넘깁니다.에이
return
성명서Expression
시도그것을 포함하는 메소드의 호출자에게 제어권을 넘깁니다. 의 가치Expression
메소드 호출의 값이됩니다.앞의 설명은 "시도컨트롤을 전송하는"단지"통제를 이전하다"왜냐하면 만약에
try
메소드 또는 생성자 내의 명령문try
블록에는return
문 다음에 어떤finally
그 조항들try
명령문은 메서드 나 생성자의 호출자에게 제어가 전달되기 전에 가장 안쪽에서 가장 바깥쪽으로 순서대로 실행됩니다. 갑작스럽게finally
절은 a에 의해 시작된 제어 전송을 방해 할 수 있습니다.return
성명서.
다른 응답들에 덧붙여, '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();
}
}
나는 약간의 변경으로 위의 예제를 시도했다.
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에서이 코드를 디버깅 할 경우 실행 후System.out
의finally
블록하다return
성명서try
블록이 다시 실행됩니다. 그러나 이것은 사실이 아닙니다. 단순히 값 2를 반환합니다.
i
원시 객체가 아니라 Integer 객체입니다. - Yamcha
여기에케빈의 대답. 반환되는 표현식이 이전에 평가된다는 것을 아는 것이 중요합니다.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 가상 머신이 다른 이유로 착수 한 경우).
이것을 생각해 볼 수있는 논리적 인 방법은 다음과 같습니다.
마지막으로 System.exit (0) 호출과 같은 비정상적인 프로그램 종료가 발생하지 않는 한 항상 실행됩니다. 따라서, sysout이 인쇄됩니다.
아니, 예외적 인 경우는 하나도 없습니다 // 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");
}
}
}
finally 블록은 JVM 충돌이나 호출로 인해 비정상적인 프로그램 종료가 발생하지 않는 한 항상 실행됩니다.System.exit(0)
.
그 중 finally 블록 내에서 반환 된 값은 finally 블록을 실행하기 전에 반환 된 값을 무시하므로 finally try를 사용할 때 모든 종료 점을 확인하는 데주의해야합니다.
마지막으로 항상 실행됩니다. 모든 요소가 반환 된 후에 코드에 나타나기 때문에 구현 방법을 나타내는 것은 아닙니다. 자바 런타임은 코드를 종료 할 때이 코드를 실행할 책임이 있습니다.try
블록.
예를 들어 다음과 같은 경우 :
int foo() {
try {
return 42;
}
finally {
System.out.println("done");
}
}
런타임은 다음과 같은 것을 생성합니다 :
int foo() {
int ret = 42;
System.out.println("done");
return 42;
}
캐치되지 않는 예외가 Throw되면finally
블록이 실행되고 예외가 전파됩니다.
이것은 i의 값을 12로 지정했지만 i의 값을 함수에 반환하지 않았기 때문입니다. 올바른 코드는 다음과 같습니다.
public static int test() {
int i = 0;
try {
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
return i;
}
}
finally 블록은 호출하지 않으면 항상 호출되기 때문에System.exit()
(또는 스레드가 충돌합니다).
간략하게, 공식 자바 문서 (Click이리), 그것은 쓰여진다 -
try 또는 catch 코드가 실행되는 동안 JVM이 종료되면 finally 블록은 실행되지 않을 수 있습니다. 마찬가지로, 스레드가 실행중인 경우 try 또는 catch 코드가 중단되거나 종료되면 finally 블록이 응용 프로그램 전체가 계속 실행 되더라도 실행되지 않습니다.
대답은 간단하다.예.
입력:
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
예, 전화가 걸립니다. finally 키워드를 사용하는 것이 중요합니다. try / catch 블록에서 점프하여 finally 블록을 건너 뛸 수 있다면 System.out.println을 try / catch 외부에 둡니다.
예, 그렇게 될 것입니다. try 또는 catch 블록에서 System.exit ()이 호출되거나 JVM이 충돌하지 않는 한 아무 일도 일어나지 않습니다. 블록에 return 문이 있으면 해당 return 문보다 먼저 finally 문이 실행됩니다.
예, 가능합니다. JVM 종료 또는 충돌이 발생하지 않는 경우에만
예. 블록은 항상 실행됩니다. 대부분의 개발자는이 블록을 사용하여 데이터베이스 연결, 결과 집합 개체, 명령문 개체를 닫고 Java 하이버 네이트를 사용하여 트랜잭션을 롤백합니다.
다음 프로그램을 고려하십시오.
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());
}
private static String someString() {
try {
sb.append("-abc-");
return sb.toString();
} finally {
sb.append("xyz");
}
}
}
Java 1.8.162부터 위의 코드 블록은 다음과 같은 결과를 제공합니다.
-abc-
---AGAIN---
-abc-xyz-abc-
즉,finally
객체를 해제하는 것은 다음 코드와 같은 좋은 습관입니다.
private static String someString() {
StringBuilder sb = new StringBuilder();
try {
sb.append("abc");
return sb.toString();
} finally {
sb = null;
}
}
sb.setLength(0)
마침내? - user7294900
그것은 실제로 어떤 언어에서나 사실입니다 ... 마침내 return 문 앞에 항상 실행됩니다. 리턴은 메소드 본문에 상관없이 항상 실행됩니다. 그것이 사실이 아니라면, finally 블록은별로 의미가 없을 것입니다.
finally
처음에는 ... - glglgl
결승전은 당신이 가진 어떤 경우에도 항상 호출되기 때문에. 당신은 예외가 없으며, 여전히 호출되고, 예외를 잡아냅니다. 여전히 호출됩니다.
정상적인 실행 과정에서 이것을 고려하십시오. 즉, 예외가 throw되지 않습니다. 메소드가 '무효'가 아니라면 항상 명시 적으로 무언가를 반환하지만 마침내 항상 실행됩니다.
예외가 발생하면 마지막으로 실행됩니다. 예외가 throw되지 않으면 마지막으로 실행됩니다. 예외가 잡히면 마침내 실행됩니다. 예외가 잡히지 않으면 마지막으로 실행됩니다.
JVM이 종료 될 때까지만 실행되지 않습니다.
마지막으로 블록은 항상 예외 처리 여부를 실행합니다. try 블록 전에 예외가 발생하면 finally 블록이 실행되지 않습니다.
finally
실행하고 그것은 확실히입니다.
finally
다음과 같은 경우에는 실행되지 않습니다.
사례 1 :
실행 중일 때System.exit()
.
사례 2 :
JVM / 스레드가 충돌 할 때.
사례 3 :
실행이 수동으로 중단 된 경우.
예, 왜냐하면통제 문 없음예방할 수있다.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
}
}
finally
;파이널 라이저==finalize()
방법. - jaco0646