이것에 대한 Java 사례 (C # 사례와 매우 유사)의 세부 사항은 Java 컴파일러가 메소드가 리턴 할 수 있는지 판별하는 방법과 관련이 있습니다.
특히, 규칙은 리턴 유형이있는 메소드가 정상적으로 완료 될 수 없어야하며 대신 JLS 8.4.7에 따라 갑자기 ( 반드시 리턴 문 또는 예외를 통해 표시 함) 완료해야합니다 .
메소드가 리턴 유형을 갖도록 선언 된 경우 메소드 본문이 정상적으로 완료 될 수있는 경우 컴파일 타임 오류가 발생합니다. 다시 말해, 리턴 유형이있는 메소드는 값 리턴을 제공하는 리턴 명령문을 사용하여 리턴해야합니다. "본체의 끝을 떨어 뜨려"사용할 수 없습니다 .
컴파일러는 JLS 14.21 도달 할 수없는 명령문에 정의 된 규칙을 기반으로 정상적인 종료 가 가능한지 여부를 확인합니다 .이 규칙은 정상적인 완료를위한 규칙도 정의합니다.
특히 도달 할 수없는 명령문의 규칙은 정의 된 true
상수 표현식 이있는 루프에 대해서만 특별한 경우를 만듭니다 .
while 문은 다음 중 하나 이상에 해당하면 정상적으로 완료 될 수 있습니다.
따라서 while
명령문이 정상적으로 완료 될 수 있으면 코드에 도달 할 수있는 것으로 간주되고 도달 while
가능한 중단 명령문이나 상수 true
표현식이 없는 루프 는 정상적으로 완료 될 수 있으므로 아래의 리턴 명령문이 필요 합니다.
이러한 규칙은 while
상수 true 표현식이 있고 명령문이없는 명령문 break
은 정상적으로 완료되는 것으로 간주되지 않으므로 그 아래의 코드는 도달 할 수없는 것으로 간주됩니다 . 메소드의 끝은 루프 아래에 있으며 루프 아래의 모든 항목에 도달 할 수 없으므로 메소드의 끝도 마찬가지이므로 메소드가 정상적으로 완료 되지 않을 수 있습니다 (이는 컴파일러가 찾는 것임).
if
반면에, 명령문은 루프에 제공되는 상수 표현식에 대한 특별한 예외가 없습니다.
비교:
// I have a compiler error!
public boolean testReturn()
{
final boolean condition = true;
if (condition) return true;
}
와:
// I compile just fine!
public boolean testReturn()
{
final boolean condition = true;
while (condition)
{
return true;
}
}
구별의 이유는 매우 흥미롭고 JLS에서 컴파일러 오류를 발생시키지 않는 조건부 컴파일 플래그를 허용하려는 욕구 때문입니다.
if 문은 다음과 같은 방식으로 처리 될 것으로 예상 할 수 있습니다.
if-then 문은 다음 중 하나 이상에 해당하면 정상적으로 완료 될 수 있습니다.
if-then 문에 도달 할 수 있고 조건 표현식이 값이 false 인 상수 표현식이 아닌 경우 then-statement에 도달 할 수 있습니다.
if-then-else 문은 then-statement가 정상적으로 완료되거나 else-statement가 정상적으로 완료 될 경우 정상적으로 완료 될 수 있습니다.
이 접근법은 다른 제어 구조의 처리와 일치합니다. 그러나 if 문을 "조건부 컴파일"목적으로 편리하게 사용하려면 실제 규칙이 다릅니다.
예를 들어, 다음 명령문은 컴파일 타임 오류를 발생시킵니다.
while (false) { x=3; }
그 진술 x=3;
에 도달 할 수 없기 때문에 ; 그러나 피상적으로 비슷한 경우 :
if (false) { x=3; }
컴파일 타임 오류가 발생하지 않습니다. 최적화 컴파일러는 명령문 x=3;
이 절대로 실행되지 않으며 생성 된 클래스 파일에서 해당 명령문에 대한 코드를 생략하도록 선택할 수 있지만 명령문 x=3;
은 여기에 지정된 기술적 의미에서 "도달 할 수없는"것으로 간주되지 않습니다.
이 다른 처리의 이론적 근거는 프로그래머가 다음과 같은 "플래그 변수"를 정의 할 수 있도록하는 것입니다.
static final boolean DEBUG = false;
다음과 같은 코드를 작성하십시오.
if (DEBUG) { x=3; }
DEBUG의 값을 false에서 true로 또는 true에서 false로 변경 한 다음 프로그램 텍스트를 변경하지 않고 코드를 올바르게 컴파일 할 수 있어야합니다.
조건부 break 문으로 인해 컴파일러 오류가 발생하는 이유는 무엇입니까?
루프 도달 가능성 규칙에 인용 된 것처럼 while 루프는 도달 가능한 break 문이 포함 된 경우 정상적으로 완료 될 수 있습니다. if
명령문의 then 절의 도달 가능성에 대한 규칙 은 전혀 조건 if
을 고려 하지 않으므로 이러한 조건 if
문의 then 절은 항상 도달 가능한 것으로 간주됩니다.
break
에 도달 할 수 있으면 루프 뒤의 코드도 다시 도달 할 수있는 것으로 간주됩니다. 루프 후 갑자기 종료 되는 도달 가능한 코드가 없으므로 메소드는 정상적으로 완료 할 수있는 것으로 간주되므로 컴파일러는이를 오류로 플래그합니다.