질문 1:
다음 코드가 return 문없이 컴파일되는 이유는 무엇입니까?
public int a()
{
while(true);
}
이것은 JLS§8.4.7에 의해 다루어진다 :
메소드가 리턴 유형 (§8.4.5)을 갖도록 선언 된 경우 메소드 본문이 정상적으로 완료 될 수 있으면 (§14.1) 컴파일 타임 오류가 발생합니다.
다시 말해, 리턴 유형이있는 메소드는 값 리턴을 제공하는 리턴 명령문을 사용하여 리턴해야합니다. 이 방법은 "본체의 끝을 제거"할 수 없습니다. 메소드 본문의 리턴 문에 대한 정확한 규칙은 §14.17을 참조하십시오.
메소드가 리턴 유형을 가질 수 있지만 리턴 명령문을 포함하지 않을 수 있습니다. 다음은 하나의 예입니다.
class DizzyDean {
int pitch() { throw new RuntimeException("90 mph?!"); }
}
컴파일러는 루프가 종료되지 않는다는 것을 알고 있기 때문에 ( true
물론 항상 참임), 함수가 "정상적으로 복귀 할 수 없음"(본체의 끝을 떨어 뜨림) 할 수 없다는 것을 알고 있으므로 아무 것도 없어도 return
됩니다.
질문 2 :
반면에 다음 코드는 왜 컴파일됩니까?
public int a()
{
while(0 == 0);
}
비록 다음과 같지 않지만.
public int a(int b)
{
while(b == b);
}
이 0 == 0
경우 컴파일러는 루프가 종료되지 않는다는 것을 알고 0 == 0
있습니다 ( 항상 참임). 그러나 그것은 하지 않습니다 에 대한 알고 b == b
.
왜 안돼?
컴파일러는 상수 표현식 (§15.28)을 이해 합니다. 인용 §15.2-표현의 형태 (이상하게도이 문장이 §15.28에 없기 때문에) :
일부 표현식에는 컴파일 타임에 결정할 수있는 값이 있습니다. 이들은 일정한 표현입니다 (§15.28).
귀하의 b == b
예에서 관련된 변수가 있기 때문에 상수 표현식이 아니며 컴파일 타임에 결정되도록 지정되지 않았습니다. 우리는 (경우에 있지만 항상이 경우에는 사실이 될 것 것을 볼 수 b
있었던이 double
QBrute과 같이, 지적 , 우리가 쉽게 현혹 될 수 Double.NaN
있는, 아니 ==
그 자체 )하지만, JLS 상수 표현식이 컴파일시에 결정됩니다 만 지정 컴파일러가 상수가 아닌 표현식을 평가할 수 없습니다. bayou.io 는 다음과 같은 이유에 대해 좋은 지적 을했습니다. b == b
명백하다 (er, non-NaN
값), 그러나 어떻 a + b == b + a
습니까? 아니면 (a + b) * 2 == a * 2 + b * 2
? 상수로 선을 그리는 것이 좋습니다.
따라서 표현식을 "결정"하지 않기 때문에 컴파일러는 루프가 종료되지 않는다는 것을 알지 못하므로 메소드가 정상적으로 리턴 될 수 있다고 생각합니다 return
. 따라서의 부족에 대해 불평합니다 return
.