为什么我不能从方法中显式返回 void?

发布于 2024-12-10 01:51:33 字数 339 浏览 2 评论 0原文

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

其中cancel()返回void。这不会编译...我几乎可以理解为什么。但如果我想从 void 返回一个 void,为什么不呢?相反,我最终写了这样的内容:

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

我不是在寻找代码风格建议,我想知道为什么 Java 明确禁止这种类型的 void 返回。任何信息表示赞赏,谢谢。

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

where cancel() return void. This won't compile... and I can almost understand why. But if I want to return a void from a void, why not? Instead, I end up writing something like this:

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

I'm not looking for code style suggestions, I want to know why Java expressly prohibits this type of void return. Any info is appreciated, thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

懷念過去 2024-12-17 01:51:33

这是一个有趣的问题。由于 java 强制执行返回类型(void 是返回类型),因此您的第一个语句似乎是有意义的。我认为这只是为了惯例。由于 void 是一个占位符而不是一个对象,因此可能为了语言一致性或编译器简单性而决定将其保留。

来自 JLS

不带表达式的 return 语句必须包含在使用关键字 void 声明的方法主体中,不返回任何值(第 8.4 节),或者包含在构造函数的主体中(第 8.8 节)。

更远

准确地说,没有表达式的 return 语句总是突然完成,原因是返回没有值

It's an interesting question. Since java enforces a return type (void is a return type) your first statement seems to make sense. I would take this only for convention. Since void is a placeholder and not an object, it was probably decided to leave it out for language coherency or compiler simplicity.

From 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 (§8.4), or in the body of a constructor (§8.8).

further

To be precise, a return statement with no Expression always completes abruptly, the reason being a return with no value

鯉魚旗 2024-12-17 01:51:33

带有表达式的 return 语句返回该表达式的值。 cancel() 的类型是一个 void 表达式 - 它没有值。

从逻辑上讲,您想要执行 cancel(),然后返回 - 这就是您必须说的。这两个操作(调用 cancel() 然后返回)在逻辑上是不同的。

现在,Java可以有一种“unit”类型而不是void - 但这会影响的不仅仅是返回值。

A return statement with an expression returns the value of that expression. The type of cancel() is a void expression - it doesn't have a value.

Logically you want to execute cancel(), and then return - so that's what you have to say. The two actions (calling cancel() and then returning) are logically distinct.

Now Java could have a sort of "unit" type instead of void - but that would affect rather more than just return values.

━╋う一瞬間旳綻放 2024-12-17 01:51:33

就像这样写:

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

所以,我认为 void 不是 Java 中的 type。在 C++ 中,return cancel(); 是合法的。作为一个熟悉 Java 的 C++ 程序员,答案是:Java 语法不支持很多东西。也许是为了简单或可读性。

注意:void f() 声明类似于 pascal 中的 procedure f() 声明,过程不能返回任何值,例如函数,因此我们必须在单独的语句中调用它们。

It's like writing:

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

So, I think void is not a type in Java. In C++, return cancel(); is legal. As a C++ programmer who is familiar with Java the answer is: Many things are not supported in Java syntax. Maybe for simplicity or readibility.

Note: A void f() declaration is similar to a procedure f() declaration in pascal and a procedure could not return any value such as functions, so we must call them in a separated statement.

那片花海 2024-12-17 01:51:33

void is not a type. If you use the Void type instead of the void keyword, however, your code will work, but: You'll manually have to return null in all exit points from your method.

迷爱 2024-12-17 01:51:33

因为你不会返回voidvoid 不是一个值,因此无法返回。

Because you don't return void. void is not a value, so it can't be returned.

寂寞陪衬 2024-12-17 01:51:33

这是同义反复。意思是,void 定义该方法没有返回值。因此,当 void 根本不返回时,你怎么能“返回 void”呢?

It's a tautology. Meaning, void defines that the method has no return value. Therefore, how can you "return void" when void is no return at all?

朕就是辣么酷 2024-12-17 01:51:33

简短回答

return cancel() 语句必须返回有效值,但方法声明 void run() 声明 run() 不返回有效值返回一个值;因此,run() 中的 return cancel() 是一个错误。 return 语句(不带表达式)尝试将控制权转移给调用者,当方法返回类型为 void 时使用;因此,这不是一个错误。

长答案

JLS *return* 语句 部分 指出:

不带表达式的 return 语句尝试将控制权转移到包含它的方法或构造函数的调用者。 [...] 带有表达式的 return 语句必须包含在声明为返回值的方法声明中(第 8.4 节),否则会发生编译时错误。表达式必须表示某种类型 T 的变量或值,否则会发生编译时错误。类型 T 必须可分配(第 5.2 节)给方法的声明结果类型,否则会发生编译时错误。

JLS 方法返回类型 部分 指出:

方法的返回类型声明方法返回值的类型(如果它返回值),或者声明该方法为 void。当且仅当满足以下条件时,具有返回类型 R1 的方法声明 d1 可以返回类型替换另一个具有返回类型 R2 的方法 d2: [...] * 如果 R1 为 void,则 R2 为 void。

JLS 类型、值和变量第一段指出:

Java 编程语言是一种强类型语言,这意味着每个变量和每个表达式都有一个在编译时已知的类型。类型限制变量(第 4.12 节)可以保存的值或表达式可以生成的值,限制这些值支持的操作,并确定操作的含义。

JLS 类型和值的种类部分指出:

Java 编程语言中有两种类型:基本类型(第 4.2 节)和引用类型(第 4.3 节)。相应地,有两种数据值可以存储在变量中、作为参数传递、由方法返回并进行操作:原始值(第 4.2 节)和引用值(第 4.3 节)。

现在只需再引述几句。 JLS 表达式语句部分< /a> 状态:

与 C 和 C++ 不同,Java 编程语言仅允许将某些形式的表达式用作表达式语句。请注意,Java 编程语言不允许“强制转换为 void”——void 不是类型

JLS 方法主体部分指出:

如果方法被声明为 void,则其主体不得包含任何具有表达式的返回语句 (§14.17)。

最后,JLS 方法声明部分指出:

方法声明要么指定方法返回值的类型,要么使用关键字 void 指示该方法不返回值。

现在,当我们将它们拼凑在一起时,我们可以推断出以下结论:

  • 如果 return 语句包含表达式,则该表达式的计算结果必须为有效值。
  • 有效的返回表达式值必须是原始类型或引用类型。
  • void 不是有效的值类型。
  • 使用 void 返回类型声明的方法不返回任何值。
  • 方法 void run() 不返回值。
  • run() 中,return(不带表达式)会很乐意将控制权转移给调用者。
  • run() 中,return some expression 是一个错误,因为 some expression 必须是有效值,并且 run() > 不返回值。

Short Answer

The return cancel() statement must return a valid value, but the method declaration void run() declares that run() does not return a value; hence, return cancel() in run() is an error. The return statement (without an expression) attempts to transfer control to the caller and is used when the method return type is void; hence, not an error.

Long Answer

The JLS The *return* Statement section states:

A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it. [...] A return statement with an Expression must be contained in a method declaration that is declared to return a value (§8.4) 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 (§5.2) to the declared result type of the method, or a compile-time error occurs.

The JLS Method Return Type section states:

The return type of a method declares the type of value a method returns, if it returns a value, or states that the method is void. A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold: [...] * If R1 is void then R2 is void.

The JLS Types, Values, and Variables chapter, first paragraph states:

The Java programming language is a strongly typed language, which means that every variable and every expression has a type that is known at compile time. Types limit the values that a variable (§4.12) can hold or that an expression can produce, limit the operations supported on those values, and determine the meaning of the operations.

The JLS The Kinds of Types and Values section states:

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.
飘逸的'云 2024-12-17 01:51:33

return x 明确表示“返回值 x”,无论该类型是什么(当然,该类型仍然必须与该语句所在的任何函数的返回类型相匹配)。

严格来说,void 是一种类型的不存在,推而广之,就是不存在值 - 因此返回一个值是没有意义的,就像它一样声明 void 变量没有意义(也是不允许的)。

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.

云裳 2024-12-17 01:51:33

Void 不是真实类型。 Void 只是一个占位符,使方法定义的语法更加一致。这不是java的创新;而是java的创新。这是从 C 继承的。

这就是编译器不允许您编写 return cancel() 的原因,即使方法 cancel()void >。

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.

不顾 2024-12-17 01:51:33

void 不是一种类型。方法定义中的 void 只是一个占位符,表示不返回任何内容。

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

似梦非梦 2024-12-17 01:51:33

有趣的想法。主要问题是语言规范,它将 return 语句定义为由 return 组成。 void 方法不是表达式,因此不允许构造。

您发现可以通过执行 void 方法然后返回来复制功能,因此没有真正的理由允许它。

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.

沧桑㈠ 2024-12-17 01:51:33

来自 JLS:

不带表达式的返回语句必须包含在
使用关键字 void 声明的方法,不返回任何内容
值,或在构造函数的主体中

......

带有表达式的返回语句必须包含在方法中
声明返回一个值或编译时
发生错误。表达式必须表示变量或某些值
类型 T,否则会发生编译时错误。类型 T 必须是可赋值的
方法的声明结果类型,或编译时错误
发生。

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.

原野 2024-12-17 01:51:33

Java 语法 实际上并不关心方法调用的类型,所以这不是问题。它必须是在类型检查系统中更下游的东西。我认为最重要的是,如果在 return 关键字之后包含语法上可选的语句,那么系统期望传递一个值。 void 当然一种类型,但是没有void 类型的值。

但是,当然,这些都不能真正解释你问题的答案。正如您所指出的,没有理由不允许使用这种习惯用法。但也没有正当理由允许这样做。所以这是一个折腾。人们可以尝试为他们所做的事情合理化,但这可能毫无意义。

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.

疑心病 2024-12-17 01:51:33

处理这个问题的正确方法是:

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

A proper way to handle this would be:

void run() {
...
if (done) {
    cancel();
    return;
    }
...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文