[java] 무효가 아닌 메소드 컴파일에서 누락 된 리턴 문

void아닌 메소드return 문 이 누락 되어 코드가 여전히 컴파일 되는 상황이 발생했습니다 . while 루프 이후의 명령문은 도달 할 수 없으며 (데드 코드) 절대 실행되지 않습니다. 그러나 컴파일러가 왜 무언가를 반환하는 것에 대해 경고하지 않습니까? 아니면 왜 언어를 사용하여 무한 루프를 가지고 있고 아무것도 반환하지 않는 비 무효 메소드를 가질 수 있습니까?

public int doNotReturnAnything() {
    while(true) {
        //do something
    }
    //no return statement
}

while 루프에 break 문 (조건문 하나)을 추가하면 컴파일러는 악명 높은 오류 ( Method does not return a valueEclipse 및 Not all code paths return a valueVisual Studio) 에 대해 불평합니다 .

public int doNotReturnAnything() {
    while(true) {
        if(mustReturn) break;
        //do something
    }
    //no return statement
}

이것은 Java와 C # 모두에 해당됩니다.



답변

왜 언어를 사용하면 무한 루프를 가지고 있고 아무것도 반환하지 않는 비 공백 메소드를 가질 수 있습니까?

무효가 아닌 메소드의 규칙 은 리턴하는 모든 코드 경로가 값을 리턴해야 하며 해당 규칙이 프로그램에서 충족되는 것입니다. 리턴하는 0 개의 코드 경로 중 0은 값을 리턴합니다. 이 규칙은 “모든 비 공백 메소드는 리턴하는 코드 경로를 가져야합니다”는 아닙니다.

이를 통해 다음과 같은 스텁 메소드를 작성할 수 있습니다.

IEnumerator IEnumerable.GetEnumerator() 
{ 
    throw new NotImplementedException(); 
}

그것은 무효가 아닌 방법입니다. 그것은 갖는 인터페이스를 충족하기 위해 비 공간있어서한다. 그러나이 구현을 아무것도 반환하지 않기 때문에 불법으로 만드는 것은 어리석은 것처럼 보입니다.

당신의 방법은 때문에의 도달 끝 지점을 가지고 goto(A는 기억 while(true)쓰기 단지 더 즐거운 방법입니다 goto대신의) throw(의 또 다른 형태 인 goto) 관련이 없습니다.

컴파일러가 무언가를 반환하는 것에 대해 경고하지 않는 이유는 무엇입니까?

컴파일러는 코드가 잘못되었다는 좋은 증거가 없기 때문입니다. 누군가가 글을 썼는데 while(true), 그 일을 한 사람이 자신이하는 일을 알고있을 것 같습니다.

C #의 도달 가능성 분석에 대한 자세한 내용은 어디서 볼 수 있습니까?

주제에 대한 내 기사를 참조하십시오.

ATBG : 사실상 그리고 법적인 접근성

그리고 C # 사양을 읽는 것도 고려할 수 있습니다.


답변

Java 컴파일러는 도달 할 수없는 코드 ( while루프 후 코드)를 찾을 수있을 정도로 똑똑합니다.

그 이후로 도달 할 수없는 , 아무 소용이없는 추가에서 return이 문 (후 while종료)

조건부와 동일 if

public int get() {
   if(someBoolean) {   
     return 10;
   }
   else {
     return 5;
   }
   // there is no need of say, return 11 here;
}

부울 조건 someBooleantrue또는 로만 평가할 수 있으므로 해당 코드에 도달 할 수 없고 Java가 이에 대해 불평하지 않기 때문에 명시 적으로 after false를 제공 할 필요 가 없습니다.return if-else


답변

컴파일러는 while루프가 실행을 멈추지 않으므로 메소드가 완료 return되지 않으므로 명령문이 필요하지 않다는 것을 알고 있습니다.


답변

루프가 상수로 실행되고 있다고 가정하면 컴파일러는 무한 루프라는 것을 알고 있습니다.

변수를 사용하면 컴파일러가 규칙을 시행합니다.

이것은 컴파일되지 않습니다 :

// Define other methods and classes here
public int doNotReturnAnything() {
    var x = true;

    while(x == true) {
        //do something
    }
    //no return statement - won't compile
}


답변

Java 스펙은이라는 개념을 정의합니다 Unreachable statements. 코드에 도달 할 수없는 진술을 할 수 없습니다 (컴파일 타임 오류입니다). while (true) 이후에는 return 문을 사용할 수 없습니다. 자바 문장. while(true);문 그러므로 당신이 필요하지 않은, 정의에 의해 다음 문에 도달 할 수 있습니다 return문을.

동안 참고하는 것이 앞뒤가 맞지 문제가 일반적인 경우 결정 불가능하다, 도달 할 수없는 문의 정의는 정지보다 더 엄격하다. 프로그램이 확실히 멈추지 않는 매우 구체적인 경우를 결정하고 있습니다. 컴파일러는 이론적으로 모든 무한 루프와 도달 할 수없는 명령문을 감지 할 수 없지만 스펙에 정의 된 특정 케이스 (예 : while(true)케이스) 를 감지해야합니다.


답변

컴파일러는 while루프가 무한 하다는 것을 알기에 충분히 똑똑합니다 .

따라서 컴파일러는 당신을 생각할 수 없습니다. 그 코드를 작성 했는지 추측 할 수 없습니다 . 메소드의 리턴 값도 동일합니다. 메소드의 반환 값으로 아무것도하지 않으면 Java가 불평하지 않습니다.

따라서 귀하의 질문에 대답하십시오 :

컴파일러는 코드를 분석하고 실행 경로가 없어서 함수 끝에서 떨어지는 것으로 확인한 후 OK로 끝납니다.

무한 루프에 대한 합법적 인 이유가있을 수 있습니다. 예를 들어 많은 앱이 무한 메인 루프를 사용합니다. 다른 예는 요청을 무한정 기다릴 수있는 웹 서버입니다.


답변

타입 이론에는, 다른 모든 타입 (!)의 서브 클래스 인 하부 타입 (bottom type) 이라고 불리는 것이 있으며 다른 것들 중에서 종료되지 않음을 나타내는 데 사용됩니다. 예외는 일종의 비 종료 유형으로 간주 될 수 있으며 일반 경로를 통해 종료되지 않습니다.

따라서 이론적 인 관점에서 종결되지 않는 이러한 문장은 하위 유형 인 int의 하위 유형을 반환하는 것으로 간주 될 수 있으므로 유형 관점에서 결국 반환 값을 얻습니다. 그리고 하나의 유형이 실제로 하나를 반환하지 않기 때문에 int를 포함하여 다른 모든 유형의 하위 클래스가 될 수 있다는 것은 전혀 의미가 없습니다.

어쨌든 명시 적 형식 이론을 통해, 컴파일러 (컴파일러 작성자)는 종료되지 않은 명령문 이후에 반환 값을 요청하는 것이 어리 석다는 것을 인식합니다. 해당 값이 필요할 수있는 경우는 없습니다. (종료되지 않을 것을 알고 있지만 무언가를 반환하기를 원할 때 컴파일러가 경고하도록하는 것이 좋을 수 있습니다.하지만 스타일 체커에 대해서는 왼쪽 표식이 더 좋습니다. 다른 이유로 (예 : 서브 클래 싱) 길을 찾지 만 실제로는 비 종료를 원합니다.)