인터넷에는 Java의 예외 포착 메커니즘 중 try...catch...finally 블록의 finally 문이 확실히 실행될 것인지에 대해 논의하는 사람들이 많이 있습니다. 많은 사람들이 아니오라고 말합니다. 물론 그들의 대답은 옳습니다. 제 실험 후에는 finally 문이 실행되지 않는 상황이 최소한 두 가지 있습니다.
(1) try 문 이전과 같이 try 문이 실행되지 않습니다. 이는 finally 문이 실행되기 위한 필요조건이지만 충분조건은 아니라는 것을 보여줍니다. 해당 try 문을 실행해야 합니다.
(2) try 블록에 System.exit(0); JVM도 중지되고 모든 것이 종료됩니다. finally 문도 실행되지 않습니다.
물론 많은 사람들이 finally 문 실행과 return 사이의 관계에 대해 논의하는데, 이는 상당히 혼란스럽습니다. finally 문이 try return 이전에 실행되는지, 아니면 후에 실행되는지 궁금합니다. 나는 또한 그들이 말한 것이 정확하다고 생각하지 않습니다. finally 문은 try return 문이 실행된 후 return이 반환되기 전에 실행됩니다. 이 진술은 약간 모순적입니다. 어쩌면 내 표현이 충분히 명확하지 않을 수도 있습니다. 아래에서는 이를 뒷받침하는 몇 가지 결과와 예시를 제시하겠습니다. 질문이 있으시면 언제든지 문의해 주세요.
1. finally 문은 return 문이 실행된 후 return 전에 실행됩니다.
public class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
}
catch (Exception e) {
System.out.println("catch block");
}
finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
}
return b;
}
}
로그인 후 복사
실행 결과는
try block
finally block
b>25, b = 100
100
로그인 후 복사
로그인 후 복사
return 문을 실행한 후 finally 문을 실행했다는 뜻인데 직접 반환하지는 않지만, finally 문이 실행될 때까지 기다립니다.
이 예가 이 상황을 설명하기에 충분하지 않다고 생각되면 결론을 강화하는 또 다른 예가 있습니다.
public class FinallyTest1 {
public static void main(String[] args) {
System.out.println(test11());
}
public static String test11() {
try {
System.out.println("try block");
return test12();
} finally {
System.out.println("finally block");
}
}
public static String test12() {
System.out.println("return statement");
return "after return";
}
}
로그인 후 복사
실행 결과는 다음과 같습니다.
try block
return statement
finally block
after return
로그인 후 복사
try에 대한 설명 return 문이 먼저 실행되지만 즉시 반환되지 않습니다. finally의 실행이 완료될 때까지 기다리십시오. finally에도 return 문이 있으면 try에 반환할 수 없습니까? 돌아왔어? 아래를 참조하세요.
2 finally 블록의 return 문은 try 블록의 return return을 재정의합니다.
public class FinallyTest2 {
public static void main(String[] args) {
System.out.println(test2());
}
public static int test2() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
return 200;
}
// return b;
}
}
로그인 후 복사
실행 결과는 다음과 같습니다.
try block
finally block
b>25, b = 100
200
로그인 후 복사
이는 try에 return 문이 있는지 여부에 관계없이 return in이 최종적으로 직접 반환된다는 것을 보여줍니다. 여기에 작은 세부 사항이 있습니다. finally에 return을 추가하면 외부의 return b finally는 도달할 수 없는 명령문이 됩니다. 즉, 실행할 수 없으므로 주석 처리해야 합니다. 그렇지 않으면 컴파일러가 오류를 보고합니다.
여기서 다시 생각해 볼 수 있습니다. finally에 return 문이 없지만 b의 값이 수정된 경우 try의 return은 수정된 값을 반환합니까, 아니면 원래 값을 반환합니까? 아래를 참조하세요.
3. finally 문에 반환 값을 덮어쓰는 return 문이 없으면 finally의 수정으로 인해 원래 반환 값이 변경될 수도 있고 변경되지 않을 수도 있습니다.
테스트 사례 1:
public class FinallyTest3 {
public static void main(String[] args) {
System.out.println(test3());
}
public static int test3() {
int b = 20;
try {
System.out.println("try block");
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b = 150;
}
return 2000;
}
}
로그인 후 복사
실행 결과는 다음과 같습니다.
try block
finally block
b>25, b = 100
100
로그인 후 복사
로그인 후 복사
테스트 사례 2:
import java.util.*;
public class FinallyTest6
{
public static void main(String[] args) {
System.out.println(getMap().get("KEY").toString());
}
public static Map<string> getMap() {
Map<string> map = new HashMap<string>();
map.put("KEY", "INIT");
try {
map.put("KEY", "TRY");
return map;
}
catch (Exception e) {
map.put("KEY", "CATCH");
}
finally {
map.put("KEY", "FINALLY");
map = null;
}
return map;
}
}</string></string></string>
로그인 후 복사
运行结果是:
为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了,具体请看精选30道Java笔试题解答,里面有详细的解答,简单来说就是:Java中只有传值没有传址,这也是为什么map = null这句不起作用。这同时也说明了返回语句是try中的return语句而不是 finally外面的return b;这句,不相信的话可以试下,将return b;改为return 294,对原来的结果没有一点影响。
这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?请看下面。
4. try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况。
public class FinallyTest4 {
public static void main(String[] args) {
System.out.println(test4());
}
public static int test4() {
int b = 20;
try {
System.out.println("try block");
b = b / 0;
return b += 80;
} catch (Exception e) {
b += 15;
System.out.println("catch block");
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
return 204;
}
}
로그인 후 복사
运行结果是:
try block
catch block
finally block
b>25, b = 35
85
로그인 후 복사
这里因 为在return之前发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch 语句和最终的finally语句,此时两者对b的修改都影响了最终的返回值,这时return b;就起到作用了。当然如果你这里将return b改为return 300什么的,最后返回的就是300,这毋庸置疑。
这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?看下面。
5. 当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样。
public class FinallyTest5 {
public static void main(String[] args) {
System.out.println(test5());
}
public static int test5() {
int b = 20;
try {
System.out.println("try block");
b = b /0;
return b += 80;
} catch (Exception e) {
System.out.println("catch block");
return b += 15;
} finally {
System.out.println("finally block");
if (b > 25) {
System.out.println("b>25, b = " + b);
}
b += 50;
}
//return b;
}
}
로그인 후 복사
运行结果如下:
try block
catch block
finally block
b>25, b = 35
35
로그인 후 복사
说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。
最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中 return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群:159610322 我们一起学Java!
위 내용은 Java finally 문 사용에 대한 몇 가지 참고 사항의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!