Programing

메서드에서 명시 적으로 void를 반환 할 수없는 이유는 무엇입니까?

lottogame 2021. 1. 8. 07:45
반응형

메서드에서 명시 적으로 void를 반환 할 수없는 이유는 무엇입니까?


void run() {
    ...
    if (done) return cancel();
    ...
}

여기서 cancel()return void. 이것은 컴파일되지 않습니다 ... 그리고 나는 그 이유를 거의 이해할 수 있습니다 . 그러나 무효에서 무효를 반환하고 싶다면 왜 안됩니까? 대신 다음과 같이 작성합니다.

if (done) {
    cancel();
    return;
}

나는 코드 스타일 제안을 찾는 것이 아니라 Java가 이러한 유형의 무효 반환을 명시 적으로 금지하는 이유를 알고 싶습니다. 모든 정보를 주셔서 감사합니다.


표현식이있는 return 문은 해당 표현식의 값을 반환합니다. 의 유형은 cancel()무효 표현이다 - 그것은하지 않습니다 값을.

논리적으로 실행 cancel()하고 반환 하고 싶습니다 -그래서 당신이 말해야 할 것입니다. 두 작업 (호출 cancel()및 반환)은 논리적으로 구별됩니다.

이제 Java - 대신 일종의 "단위"유형을 가질 있지만 이는 반환 값보다 더 많은 영향을 미칩니다.void


흥미로운 질문입니다. 자바가 반환 유형을 강제하기 때문에 ( void반환 유형) 첫 번째 진술이 의미가있는 것 같습니다. 나는 이것을 컨벤션을 위해서만 가져갈 것입니다. void개체가 아닌 자리 표시 자 이므로 언어 일관성이나 컴파일러 단순성을 위해 제외하기로 결정했을 것입니다.

에서 JLS

Expression이없는 return 문은 값을 반환하지 않도록 (§8.4) 또는 생성자 본문 (§8.8)에 void 키워드를 사용하여 선언 된 메서드 본문에 포함되어야합니다.

더욱이

정확히 말하면 Expression이없는 return 문은 항상 갑작스럽게 완료되며, 그 이유는 값이없는 반환 때문입니다.


다음과 같이 작성합니다.

void v=(void)1; 
return (v);

그래서 나는 Java void가 아니라고 생각 type합니다.

C ++에서는 return cancel();합법적입니다.

Java에 익숙한 C ++ 프로그래머로서 대답은 다음과 같습니다. Java 구문에서는 많은 것이 지원되지 않습니다. 단순성 또는 가독성을 위해.

참고 : void f()선언은 procedure f()파스칼 선언 과 유사 하며 프로시 저는 함수와 같은 값을 반환 할 수 없으므로 분리 된 문에서 호출해야합니다.


void유형이 아닙니다. 그러나 키워드 Void대신 유형 을 사용하면 void코드가 작동하지만 : return null메서드의 모든 종료 지점에서 수동으로 수행해야합니다 .


당신이 반환 하지 않기 때문에 void. void값이 아니므로 반환 할 수 없습니다.


그것은 팽팽한 것입니다. 의미, void는 메서드에 반환 값이 없음을 정의합니다. 따라서 무효가 전혀 반환되지 않을 때 어떻게 "공허를 반환"할 수 있습니까?


짧은 대답

return cancel()문은 유효한 값을 반환해야하지만, 메소드 선언은 void run()그 선언 run()값을 반환하지 않습니다 따라서 return cancel()in run()은 오류입니다. return문 (표현식 없음)은 호출자에게 제어를 전송하려고 시도하며 메서드 반환 유형이 다음과 같을 때 사용됩니다 void. 따라서 오류가 아닙니다.

긴 답변

JLS의 The *return* Statement섹션 상태 :

Expression이없는 return 문은이를 포함하는 메서드 또는 생성자의 호출자에게 제어를 전송하려고합니다. [...] Expression이있는 return 문은 값 (§8.4)을 반환하도록 선언 된 메서드 선언에 포함되어야합니다. 그렇지 않으면 컴파일 타임 오류가 발생합니다. Expression은 T 유형의 변수 또는 값을 나타내야합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다. T 형식은 메서드의 선언 된 결과 형식에 할당 할 수 있어야합니다 (§5.2). 그렇지 않으면 컴파일 타임 오류가 발생합니다.

JLS Method Return Type섹션 은 다음 같이 설명합니다.

메서드의 반환 유형은 값을 반환하는 경우 메서드가 반환하는 값의 유형을 선언하거나 메서드가 무효임을 나타냅니다. 리턴 유형이 R1 인 메소드 선언 d1은 리턴 유형이 R2 인 다른 메소드 d2에 대해 리턴 유형 대체 가능합니다. 다음 조건이 유지되는 경우에만 : [...] * R1이 void이면 R2는 무효입니다.

JLS Types, Values, and Variables장의 첫 번째 단락은 다음과 같이 설명합니다.

Java 프로그래밍 언어는 강력한 유형의 언어입니다. 즉, 모든 변수와 모든 표현식에는 컴파일 시간에 알려진 유형이 있습니다. 형식은 변수 (§4.12)가 보유 할 수 있거나식이 생성 할 수있는 값을 제한하고, 해당 값에서 지원되는 작업을 제한하고, 작업의 의미를 결정합니다.

JLS The Kinds of Types and Values섹션 은 다음 같이 설명합니다.

There are two kinds of types in the Java programming language: primitive types (§4.2) and reference types (§4.3). There are, correspondingly, two kinds of data values that can be stored in variables, passed as arguments, returned by methods, and operated on: primitive values (§4.2) and reference values (§4.3).

Just a few more quotes now. The JLS Expression Statements section states:

Unlike C and C++, the Java programming language allows only certain forms of expressions to be used as expression statements. Note that the Java programming language does not allow a "cast to void"-void is not a type

The JLS Method Body section states:

If a method is declared void, then its body must not contain any return statement (§14.17) that has an Expression.

And, finally, the JLS Method Declarations section states:

A method declaration either specifies the type of value that the method returns or uses the keyword void to indicate that the method does not return a value.

Now, when we piece it all together, we can deduce the following:

  • If a return statement contains an expression, the expression must evaluate to a valid value.
  • A valid return expression value must be a primitive type or a reference type.
  • void is not a valid value type.
  • A method declared with a void return type, returns no value.
  • Method void run() does not return a value.
  • In run(), return, without an expression, will happily transfer control to the caller.
  • In run(), return some expression is an error because some expression must be a valid value and run() does not return a value.

return x explicitly means "return the value x", regardless of what that type is (the type, of course, still has to match the return type of whatever function that statement is placed in).

void is, strictly speaking, the absence of a type, and by extension, the absence of a value - so it does not make sense to return one, just like it does not make sense (and is not allowed) to declare a void variable.


Void is not a real type. Void is just a place holder to make syntax of methods definition more consistent. This is not the java innovation; this is inherited from C.

This is the reason that compiler does not allow you to write return cancel() even if method cancel() is void.


void is not a type. void in the method definition is just a placeholder for returns nothing.


Interesting idea. The main issue is the language spec, which defines a return statement as being composed of return <expression>. A void method is not an expression, so the construct isn't permitted.

You've found that you can replicate the functionality by executing the void method and then returning, so there's no real reason to allow it.


From the JLS:

A return statement with no Expression must be contained in the body of a method that is declared, using the keyword void, not to return any value, or in the body of a constructor

...

A return statement with an Expression must be contained in a method declaration that is declared to return a value or a compile-time error occurs. The Expression must denote a variable or value of some type T, or a compile-time error occurs. The type T must be assignable to the declared result type of the method, or a compile-time error occurs.


The Java grammar actually doesn't care about the type of a method call, so that's not the issue. It has to be something farther down the chain, in the type-checking system. I think the bottom line is that if a grammatically optional statement is included after the return keyword, then the system expects a value to pass on. void certainly is a type, but there are no values with type void.

But, of course, none of this really explains the answer to your question. As you pointed out, there's no reason why this idiom should not be allowed. But there's also no valid reason to allow it. So it's a toss up. One could try to rationalize why they did what they did, but that would probably be pointless.


A proper way to handle this would be:

void run() {
...
if (done) {
    cancel();
    return;
    }
...
}

ReferenceURL : https://stackoverflow.com/questions/7795303/why-cant-i-explicitly-return-void-from-a-method

반응형