반환 유형이 있는 Java 메서드(return 스테이트먼트 없이 컴파일)
질문 1:
다음 코드는 왜 반환문을 사용하지 않고 컴파일됩니까?
public int a() {
while(true);
}
하면 " " " "가 표시됩니다.Unreachable Code Error
.
질문 2:
한편, 다음과 같은 코드가 컴파일 되는 이유는 무엇입니까?
public int a() {
while(0 == 0);
}
다음과 같이 하지 않아도 됩니다.
public int a(int b) {
while(b == b);
}
질문 1:
다음 코드는 왜 반환문을 사용하지 않고 컴파일됩니까?
public int a() { while(true); }
이것은 JLS®8.4.7의 대상입니다.
메서드가 반환 유형(88.4.5)으로 선언된 경우 메서드의 본문(1414.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
.
왜 안 되나요?
컴파일러는 상수 표현식(1515.28)을 이해한다.인용 §15.2 - 표현의 형태 (이상하게도 이 문장이 §15.28에 없기 때문에):
일부 식에는 컴파일 시 확인할 수 있는 값이 있습니다.이것들은 상수식입니다( 「15.28」).
고객님의 고객명b == b
예를 들어 변수가 관련되어 있기 때문에 상수 식이 아니며 컴파일 시 결정되도록 지정되지 않았습니다.이 경우에는 항상 해당된다는 것을 알 수 있습니다(단,b
weredouble
QBrute가 지적했듯이, 우리는 쉽게 속아 넘어갈 수 있다.Double.NaN
(그 자체는 아니지만) 그러나 JLS에서는 상수 표현은 컴파일 시에 결정된다고만 규정하고 있습니다.이것에 의해, 컴파일러는 부정 표현에 대한 평가를 실시할 수 없게 됩니다.bayou.io 는, 다음의 이유에 대해 좋은 점을 제시했습니다.컴파일 시 변수를 포함하는 식을 결정하려고 하면 어디에서 멈출 수 있습니까? b == b
명백하다(er, non-to-to-).NaN
값)에 대해 설명하겠습니다.a + b == b + a
아니면?(a + b) * 2 == a * 2 + b * 2
상수에 선을 긋는 것은 의미가 있습니다.
따라서 표현식을 "결정"하지 않기 때문에 컴파일러는 루프가 종료되지 않는다는 것을 알지 못하기 때문에 메서드는 정상적으로 반환될 수 있다고 생각합니다.이것은 사용할 필요가 있기 때문에 허용되지 않습니다.return
. 그래서 그것은 그 부족에 대해 불평합니다.return
.
메서드 반환 유형을 지정된 유형의 값을 반환한다는 약속이 아니라 지정된 유형의 값이 아닌 값을 반환하지 않는다는 약속으로 생각하면 흥미로울 수 있습니다.따라서 반환하지 않는 것은 약속을 어기는 것이 아니기 때문에 다음 중 하나가 합법입니다.
영구 루프:
X foo() { for (;;); }
영속적인 반복:
X foo() { return foo(); }
예외 삭제:
X foo() { throw new Error(); }
(재귀에 대해 생각해 보면 재미있습니다.컴파일러는 메서드가 type 값을 반환할 것으로 믿고 있습니다.X
(그것이 무엇이든) 하지만 그것은 사실이 아닙니다.왜냐하면 이 코드에는 작성 또는 조달 방법에 대한 아이디어가 존재하지 않기 때문입니다.X
.)
바이트 코드를 보면 반환되는 항목이 정의와 일치하지 않으면 컴파일 오류가 발생합니다.
예:
for(;;)
는 바이트 코드를 표시합니다.
L0
LINENUMBER 6 L0
FRAME SAME
GOTO L0
반환 바이트코드가 없는 것에 주의해 주세요.
이것은 리턴에 도달하지 않기 때문에 잘못된 유형을 반환하지 않습니다.
비교를 위해 다음과 같은 방법을 사용합니다.
public String getBar() {
return bar;
}
다음 바이트 코드를 반환합니다.
public java.lang.String getBar();
Code:
0: aload_0
1: getfield #2; //Field bar:Ljava/lang/String;
4: areturn
"reference 반환"을 의미하는 "areturn"에 주의하십시오.
다음 작업을 수행합니다.
public String getBar() {
return 1;
}
다음 바이트 코드를 반환합니다.
public String getBar();
Code:
0: iconst_1
1: ireturn
이제 정의의 유형이 반환 유형(return int)과 일치하지 않음을 알 수 있습니다.
결론적으로 메서드에 리턴 경로가 있는 경우 해당 경로가 리턴 유형과 일치해야 합니다.그러나 바이트 코드에 리턴 패스가 전혀 생성되지 않아 규칙을 위반하지 않는 경우가 있습니다.
언급URL : https://stackoverflow.com/questions/31050114/java-method-with-return-type-compiles-without-return-statement
'programing' 카테고리의 다른 글
1 대 다, 다 대 1 및 다 대 다의 차이점 (0) | 2022.06.19 |
---|---|
Java Runtime.getRuntime(): 명령줄 프로그램을 실행하여 출력을 가져옵니다. (0) | 2022.06.19 |
vue에서 정확히 언제 다시 발생합니까? (0) | 2022.06.18 |
Vuex 상태 내에서 맵 사용 (0) | 2022.06.18 |
디렉토리가 존재하는지 확인하려면 어떻게 해야 하나요? (0) | 2022.06.18 |