>  기사  >  Java  >  Java의 finally 및 return 실행 순서 분석(코드 예)

Java의 finally 및 return 실행 순서 분석(코드 예)

不言
不言원래의
2018-09-11 14:16:021624검색

이 기사의 내용은 Java에서 finally 및 return의 실행 순서 분석(코드 예제)에 대한 내용입니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

우리 모두는 finally의 실행 특성을 알고 있습니다.

1. 예외가 있는지 여부에 관계없이 finally 블록의 코드는 실행됩니다.

2. 실행.

그럼 질문은 실행 순서가 어떻게 되나요?

간단한 테스트 클래스 및 디컴파일된 바이트코드:

public class Test {
         publicstatic void main(String[] args) {
             System.out.println(test());
         }
 
         publicstatic int test() {
                   try{
                            System.out.println("Codesin try block.");
                            return0;
                   }catch (Exception e) {
                            System.out.println("Codesin catch block.");
                            return100;
                   }finally {
                            System.err.println("Codesin finally block.");
                   }
         }
}
/*
 public static int test();
   Code:
      0: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
      3: ldc           #5                  // String Codes in try block.
      5: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      8: iconst_0
      9: istore_0
     10: getstatic     #7                  // Field java/lang/System.err:Ljava/io/PrintStream;
     13: ldc           #8                  // String Codes in finallyblock.
     15: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     18: iload_0
     19: ireturn
     20: astore_0
     21: getstatic     #2                  // Fieldjava/lang/System.out:Ljava/io/PrintStream;
     24: ldc           #10                 // String Codes in catchblock.
     26: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     29: bipush        100
     31: istore_1
     32: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     35: ldc           #8                  // String Codes in finallyblock.
     37: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     40: iload_1
     41: ireturn
     42: astore_2
     43: getstatic     #7                  // Fieldjava/lang/System.err:Ljava/io/PrintStream;
     46: ldc           #8                  // String Codes in finallyblock.
     48: invokevirtual #6                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
     51: aload_2
     52: athrow
*/

우리가 작성한 코드를 컴파일된 바이트코드와 비교할 수 있습니다:

Java의 finally 및 return 실행 순서 분석(코드 예)

가상 머신이 우리를 위해 많은 일을 해준 것을 발견했습니다. finally 문을 삽입합니다. try, catch 및 return 문 사이를 차단합니다. 이것이 예외가 있는지 여부, 반환 여부에 관계없이 finally가 실행되는 이유입니다. finally가 실행될 것이므로 finally에서 반환되는 것은 무엇이든 반환됩니다. finally 이전의 모든 반환은 유효하지 않으므로 return의 의미는 무엇입니까? 따라서 실제로 finally 블록은 반환을 허용하지 않습니다. Eclipse 컴파일러는 경고 메시지를 표시합니다. finallyblock이 정상적으로 완료되지 않습니다.

여러 상황에 대한 테스트 코드

try{ return; }catch(){} finally{} return;

테스트 코드:

1. 참조 데이터 유형이 참조 객체를 변경합니다.

   public static int test1(){
      int a = 10;
      try{
         a = 20;
         return a;
      }catch(Exception e){
         //other codes.
      }finally{
         a += 5;
         //other codes.
      }
      return a;
   }//最终返回值为20
   public static StringBuffer test2(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb.append("DEF");
         //other codes.
      }
      return sb;
   }//最终返回中内容为abcDEF
의 값

이 상황의 테스트에서 finally 이전에 return 문이 있으면 finally 반환 변수에 어떤 변경이 있어도 변수 자체는 다시 할당되지 않는 등 변수 자체가 다시 변경되지 않는 것을 확인할 수 있습니다. 또는 참조 유형 변수에 대한 참조를 다시 할당하면 반환 값에 기록되지 않습니다. 그러나 finally의 문이 실행되므로 finally의 참조형 변수가 가리키는 객체의 내용을 수정할 수 있으며 수정이 유효합니다. 이 상황은 이렇게 이해할 수 있습니다. 반환 문이 발생하면 가상 머신은 반환 값에 따라 집을 마음대로 철거할 수 있습니까? 할 수 없습니다. 하지만 집에 있는 사람들은 변할 수 있어요. 기본 데이터형과 참조형의 변수 자체가 집이고, 참조형 변수가 가리키는 객체의 내용이 그 집에 사는 사람이다.

이런 작은 테스트가 있습니다:

  public static StringBuffer test3(){
      StringBuffer sb = new StringBuffer("abc");
      try{
         return sb;
      }catch(Exception e){
         //other codes.
      }finally{
         sb = new StringBuffer("DEF");
         //other codes.
      }
      return sb;
   }//最终返回值中的内容为abc

1.1 try 블록에 예외가 없을 때 반환 값은 무엇입니까?

1.2 try 블록에 ArithmeticException이 있을 때 반환 값은 무엇입니까?

1.3 try 블록에 다른 예외가 있는 경우 반환 값은 무엇입니까?

답변: 모두 30개입니다. 이유는 try 블록에서 return 이전의 코드를 실행한 후, finally 블록에 return이 포함되어 있으므로 jvm이 코드를 삽입하기 때문입니다.

관련 권장사항:

Java의 try, finally 및 return 문의 실행 순서


Java의 코드 블록 실행 순서를 보여주는 예

위 내용은 Java의 finally 및 return 실행 순서 분석(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.