programing

반환 유형이 있는 Java 메서드(return 스테이트먼트 없이 컴파일)

prostudy 2022. 6. 18. 09:24
반응형

반환 유형이 있는 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 weredoubleQBrute가 지적했듯이, 우리는 쉽게 속아 넘어갈 수 있다.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.

메서드 반환 유형을 지정된 유형의 값을 반환한다는 약속이 아니라 지정된 유형의 값이 아닌 값을 반환하지 않는다는 약속으로 생각하면 흥미로울 수 있습니다.따라서 반환하지 않는 것은 약속을 어기는 것이 아니기 때문에 다음 중 하나가 합법입니다.

  1. 영구 루프:

    X foo() {
        for (;;);
    }
    
  2. 영속적인 반복:

    X foo() {
        return foo();
    }
    
  3. 예외 삭제:

    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

반응형