为什么我不能显式地从一个方法返回void ?

时间:2022-04-05 22:28:07
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:

在取消()返回void。这不会编译…我几乎能理解为什么。但如果我想从空虚中找回空虚,为什么不呢?相反,我最终写了这样的东西:

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.

我不是在寻找代码样式的建议,我想知道为什么Java明确禁止这种类型的void返回。谢谢您提供的任何信息。

14 个解决方案

#1


24  

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.

带有表达式的返回语句返回表达式的值。cancel()的类型是一个空表达式——它没有值。

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.

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

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

现在,Java可以有一种“单元”类型而不是void,但这将不仅仅影响返回值。

#2


25  

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.

这是一个有趣的问题。由于java强制执行返回类型(void是返回类型),您的第一个语句似乎是有意义的。我只把这当作惯例。由于void是一个占位符,而不是对象,所以为了语言的一致性或编译器的简洁性,它可能决定不使用它。

From JLS

从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).

没有表情的返回语句必须包含在声明的方法,使用关键字无效,不返回任何值(§8.4),或者身体的构造函数(§8.8)。

further

进一步

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

准确地说,没有表达式的返回语句总是会突然结束,原因是返回没有值

#3


9  

It's like writing:

就像写:

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

So, i think void is not a type in Java.

所以,我认为void不是Java中的类型。

In C++, return cancel(); is legal.

在c++中,返回取消();是合法的。

As a C++ programmer who familiar with Java the answer is: Many things are not supported in Java syntax. Maybe for simplicity or readibility.

作为熟悉Java的c++程序员,答案是:Java语法不支持很多东西。也许是为了简单或易读。

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.

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

#4


6  

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.

void不是类型。但是,如果您使用Void类型而不是Void关键字,那么您的代码将会工作,但是:您必须手动地在方法的所有出口点返回null。

#5


5  

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

因为你不会返回void。void不是一个值,所以不能返回。

#6


4  

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?

这是一个同义反复。void定义该方法没有返回值。因此,当虚空完全没有回报时,你怎么能“返回虚空”呢?

#7


3  

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.

return cancel()语句必须返回一个有效值,但是方法声明void run()声明run()不返回值;因此,在run()中返回cancel()是一个错误。返回语句(没有表达式)试图将控制传递给调用者,当方法返回类型为空时使用;因此,而不是一个错误。

Long Answer

The JLS The *return* Statement section states:

JLS *return*语句部分规定:

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.

没有表达式的返回语句试图将控制转移到包含它的方法或构造函数的调用方。[…)与一个表达式返回语句必须包含在方法声明,声明返回值(§8.4)或发生编译时错误。表达式必须表示某种类型T的变量或值,否则会发生编译时错误。类型T必须分配(§5.2)宣布结果类型的方法,或发生编译时错误。

The JLS Method Return Type section states:

JLS方法返回类型部分说明:

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.

方法的返回类型声明方法返回的值的类型(如果它返回一个值),或者声明该方法无效。返回类型R1的方法声明d1是返回类型替换另一个返回类型R2的方法d2,当且仅当以下条件成立时:[…]如果R1是空的,那么R2是空的。

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

JLS的类型、值和变量章节,第一段说:

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.

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

The JLS The Kinds of Types and Values section states:

JLS的类型和值部分声明:

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).

有两种类型的Java编程语言:原始类型(§4.2)和引用类型(§4.3)。相应地,有两种类型的数据值,可以存储在变量中,作为参数传递,返回的方法,和运营:原始值(§4.2)和参考价值(§4.3)。

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

现在再多说几句。JLS表达式语句部分声明:

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

与C和c++不同,Java编程语言只允许某些形式的表达式用作表达式语句。请注意,Java编程语言不允许“cast to void”——void不是类型。

The JLS Method Body section states:

JLS方法主体部分声明:

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

如果一个方法声明void,那么它的身体必须不包含任何返回语句表达式(§14.17)。

And, finally, the JLS Method Declarations section states:

最后,JLS方法声明一节规定:

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.

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

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.
  • void不是有效的值类型。
  • A method declared with a void return type, returns no value.
  • 使用void返回类型声明的方法,不返回任何值。
  • Method void run() does not return a value.
  • 方法void run()不返回值。
  • In run(), return, without an expression, will happily transfer control to the caller.
  • 在run()中,没有表达式的return将愉快地将控制权转移给调用者。
  • In run(), return some expression is an error because some expression must be a valid value and run() does not return a value.
  • 在run()中,返回某个表达式是一个错误,因为某些表达式必须是有效值,run()不返回值。

#8


2  

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).

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

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是类型的缺失,扩展地说,是值的缺失——所以返回一个值是没有意义的,就像声明一个void变量是没有意义的(而且是不允许的)一样。

#9


1  

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.

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

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

这就是为什么编译器不允许您写入return cancel(),即使方法cancel()是无效的。

#10


1  

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

void不是类型。方法定义中的void只是一个没有返回任何东西的占位符。

#11


1  

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.

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

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.

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

#12


1  

From the JLS:

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

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

...

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.

带有表达式的返回语句必须包含在声明返回值的方法声明中,否则会发生编译时错误。表达式必须表示某种类型T的变量或值,否则会发生编译时错误。类型T必须可以分配给方法声明的结果类型,否则会出现编译时错误。

#13


1  

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.

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

但是,当然,这些都不能真正解释你问题的答案。正如你所指出的,这个习语没有理由不被允许。但也没有正当的理由允许它。所以这是一个抛硬币的过程。人们可以试着解释他们为什么要这么做,但这可能毫无意义。

#14


0  

A proper way to handle this would be:

处理这种情况的适当办法是:

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

#1


24  

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.

带有表达式的返回语句返回表达式的值。cancel()的类型是一个空表达式——它没有值。

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.

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

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

现在,Java可以有一种“单元”类型而不是void,但这将不仅仅影响返回值。

#2


25  

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.

这是一个有趣的问题。由于java强制执行返回类型(void是返回类型),您的第一个语句似乎是有意义的。我只把这当作惯例。由于void是一个占位符,而不是对象,所以为了语言的一致性或编译器的简洁性,它可能决定不使用它。

From JLS

从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).

没有表情的返回语句必须包含在声明的方法,使用关键字无效,不返回任何值(§8.4),或者身体的构造函数(§8.8)。

further

进一步

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

准确地说,没有表达式的返回语句总是会突然结束,原因是返回没有值

#3


9  

It's like writing:

就像写:

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

So, i think void is not a type in Java.

所以,我认为void不是Java中的类型。

In C++, return cancel(); is legal.

在c++中,返回取消();是合法的。

As a C++ programmer who familiar with Java the answer is: Many things are not supported in Java syntax. Maybe for simplicity or readibility.

作为熟悉Java的c++程序员,答案是:Java语法不支持很多东西。也许是为了简单或易读。

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.

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

#4


6  

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.

void不是类型。但是,如果您使用Void类型而不是Void关键字,那么您的代码将会工作,但是:您必须手动地在方法的所有出口点返回null。

#5


5  

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

因为你不会返回void。void不是一个值,所以不能返回。

#6


4  

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?

这是一个同义反复。void定义该方法没有返回值。因此,当虚空完全没有回报时,你怎么能“返回虚空”呢?

#7


3  

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.

return cancel()语句必须返回一个有效值,但是方法声明void run()声明run()不返回值;因此,在run()中返回cancel()是一个错误。返回语句(没有表达式)试图将控制传递给调用者,当方法返回类型为空时使用;因此,而不是一个错误。

Long Answer

The JLS The *return* Statement section states:

JLS *return*语句部分规定:

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.

没有表达式的返回语句试图将控制转移到包含它的方法或构造函数的调用方。[…)与一个表达式返回语句必须包含在方法声明,声明返回值(§8.4)或发生编译时错误。表达式必须表示某种类型T的变量或值,否则会发生编译时错误。类型T必须分配(§5.2)宣布结果类型的方法,或发生编译时错误。

The JLS Method Return Type section states:

JLS方法返回类型部分说明:

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.

方法的返回类型声明方法返回的值的类型(如果它返回一个值),或者声明该方法无效。返回类型R1的方法声明d1是返回类型替换另一个返回类型R2的方法d2,当且仅当以下条件成立时:[…]如果R1是空的,那么R2是空的。

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

JLS的类型、值和变量章节,第一段说:

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.

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

The JLS The Kinds of Types and Values section states:

JLS的类型和值部分声明:

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).

有两种类型的Java编程语言:原始类型(§4.2)和引用类型(§4.3)。相应地,有两种类型的数据值,可以存储在变量中,作为参数传递,返回的方法,和运营:原始值(§4.2)和参考价值(§4.3)。

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

现在再多说几句。JLS表达式语句部分声明:

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

与C和c++不同,Java编程语言只允许某些形式的表达式用作表达式语句。请注意,Java编程语言不允许“cast to void”——void不是类型。

The JLS Method Body section states:

JLS方法主体部分声明:

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

如果一个方法声明void,那么它的身体必须不包含任何返回语句表达式(§14.17)。

And, finally, the JLS Method Declarations section states:

最后,JLS方法声明一节规定:

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.

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

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.
  • void不是有效的值类型。
  • A method declared with a void return type, returns no value.
  • 使用void返回类型声明的方法,不返回任何值。
  • Method void run() does not return a value.
  • 方法void run()不返回值。
  • In run(), return, without an expression, will happily transfer control to the caller.
  • 在run()中,没有表达式的return将愉快地将控制权转移给调用者。
  • In run(), return some expression is an error because some expression must be a valid value and run() does not return a value.
  • 在run()中,返回某个表达式是一个错误,因为某些表达式必须是有效值,run()不返回值。

#8


2  

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).

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

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是类型的缺失,扩展地说,是值的缺失——所以返回一个值是没有意义的,就像声明一个void变量是没有意义的(而且是不允许的)一样。

#9


1  

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.

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

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

这就是为什么编译器不允许您写入return cancel(),即使方法cancel()是无效的。

#10


1  

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

void不是类型。方法定义中的void只是一个没有返回任何东西的占位符。

#11


1  

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.

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

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.

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

#12


1  

From the JLS:

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

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

...

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.

带有表达式的返回语句必须包含在声明返回值的方法声明中,否则会发生编译时错误。表达式必须表示某种类型T的变量或值,否则会发生编译时错误。类型T必须可以分配给方法声明的结果类型,否则会出现编译时错误。

#13


1  

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.

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

但是,当然,这些都不能真正解释你问题的答案。正如你所指出的,这个习语没有理由不被允许。但也没有正当的理由允许它。所以这是一个抛硬币的过程。人们可以试着解释他们为什么要这么做,但这可能毫无意义。

#14


0  

A proper way to handle this would be:

处理这种情况的适当办法是:

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