컴파일러 오류가없는 여러 반환 문
이것은 인터뷰 질문이었습니다.
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
return "try ...";
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
내 질문은 컴파일 시간 오류가없는 이유입니다. 내 finally
블록에 return 문이 있으면 and block finally
대신에 반환하도록 바인딩됩니다 . 이 코드를 옵션 으로 컴파일하려고 시도했는데 경고가 표시됩니다.try
catch
-Xlint
warning: [finally] finally clause cannot complete normally
Java 언어 사양에서 허용하므로 컴파일 오류가 발생하지 않습니다. 그러나 블록에 return
문을 포함하는 finally
것은 일반적으로 나쁜 생각 이기 때문에 경고 메시지를 표시합니다 .
귀하의 예에서 일어나는 일은 다음과 같습니다. 블록 의 return
명령문 try
이 실행됩니다. 그러나 finally
블록은 항상 실행되어 catch
블록이 완료된 후에 실행되어야합니다 . 여기서 return
발생하는 문은 이전 return
문의 결과를 덮어 쓰므로 메서드는 두 번째 결과를 반환합니다.
마찬가지로 finally
블록은 일반적으로 예외를 발생시키지 않아야합니다. 그렇기 때문에 경고가 finally
블록이 정상적으로 완료되어야한다고, 즉 return
예외 없이 또는 예외가 발생 해야 한다고 말하는 이유 입니다.
이것은 Java 언어 사양에 설명되어 있습니다.
finally
절의 갑작스러운 완료 는return
명령문에 의해 시작된 제어 전송을 방해 할 수 있습니다 .
try
블록 실행이 정상적으로 완료되면finally
블록이 실행되고 다음 선택 사항이 있습니다.
- 는 IF
finally
블록이 정상적으로 완료 한 후try
문이 정상적으로 완료됩니다.- 상기 중간
finally
블록이 이유에 대해 S 급격 완료 후,try
문이 완료 이유로 갑자기 대 S.
try
다른 이유 R로 인해 블록 실행이 갑자기 완료되면finally
블록이 실행되고 선택 사항이 있습니다.
- 은 if
finally
블록은 다음, 정상적으로 완료try
이유 R.위한 문이 완료 갑자기- 상기 중간
finally
블록이 이유에 대해 S 급격 완료 후try
갑자기 이유 S에 대한 문이 완료 (이성 R은 폐기된다).
return
명령문의 1 개와 정확히 1 개만 실제로 컨트롤을 호출 코드로 반환 하므로 컴파일 시간 오류가 없습니다 .
@Hoopje에서 설명했듯이, return
내에서 try
또는 catch
먼저 실행될 것이며, 각각의 return 문도 실행됩니다. 그러나 컨트롤을 호출 코드로 되돌리기 직전에 finally
블록 을 실행합니다 . 이제 이것은 block
또한 return
무언가이므로이 반환은 이전 반환을 재정의합니다.
본질적으로 다음과 같습니다.
public boolean someMethod(){
if(1 == 1){
return true;
}
return false;
}
경고를 제공하지만 컴파일 오류를 제공하지 않습니다. 컴파일러는 return 문이 실행 되지 않을 가능성이있을 때만 오류를 제공합니다 .
Brilliant Question .. 내 지식에 따르면 코드에 finally 블록을 추가하면 try 및 catch 블록의 return 문이 finally로 전송됩니다. 그것이 작동하는 방법입니다.
따라서이 경우 모든 코드 라인이 실행 중이며 디버깅을 시도 할 수 있습니다. 코드 아래에서 시도한 세 블록 모두.
public class Main {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
throw new Exception();
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
아래 링크에서 아이디어를 얻을 수 있습니다. 복수 반품 : 어떤 것이 최종 반품 값을 설정합니까?
try, catch 및 finally 블록에 return 문이 하나만 있기 때문에 코드가 제대로 작동합니다. 도달 할 수없는 return 문이 있음을 알리는 try, catch 또는 finally 블록 중 하나에 두 개의 return 문을 쓰려고하면 컴파일 오류가 발생합니다.
(짧은 대답-대답 의 굵은 이탤릭체 부분 을 읽으십시오 )
The execution flow as per the Java 8 docs. It provides you the details. You can infer execution of return statements based on the following.
A try statement with a finally block is executed by first executing the try block.
Then there is a choice:
• If execution of the try block completes normally, then the finally block is executed, and then there is a choice:
– If the finally block completes normally, then the try statement completes normally.
– If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.
• If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
– If the run-time type of V is assignment compatible with a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed.
Then there is a choice:
› If the catch block completes normally, then the finally block is executed. Then there is a choice:
» If the finally block completes normally, then the try statement completes normally.
» If the finally block completes abruptly for any reason, then the try statement completes abruptly for the same reason.
› If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice:
» If the finally block completes normally, then the try statement completes abruptly for reason R.
» If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
– If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed.
Then there is a choice:
› If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
› If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).
• If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:
– If the finally block completes normally, then the try statement completes abruptly for reason R.
– If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
the explanation is clear in this link- javaDoc
try running this:
it will print: 1, 2, 3 and then throw a division by zero Exception
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
public static String print(int a){
System.out.println(a);
return String.valueOf(a/0);
}
static String foo() {
try {
return print(1);
} catch (Exception e) {
return print(2);
} finally {
return print(3);
}
}
}
참고URL : https://stackoverflow.com/questions/30976123/multiple-return-statements-without-compiler-error
'Programing' 카테고리의 다른 글
일련의 자동화 된 테스트에 대해 setUp을 한 번만 실행 (0) | 2020.11.20 |
---|---|
mongodb의 저널 파일을 삭제해도 안전합니까? (0) | 2020.11.20 |
하나의 파일을 포드에 공유 / 마운트하는 가장 좋은 방법은 무엇입니까? (0) | 2020.11.20 |
MySQL 변경 테이블 추가 필드 이전 또는 이후 필드가 이미 존재 (0) | 2020.11.20 |
문자열로 구성된 벡터 배열 초기화 (0) | 2020.11.20 |