为什么我不能从方法中明确返回void?

时间:2011-10-17 14:33:55

标签: java void return-type

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

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

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

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

14 个答案:

答案 0 :(得分:25)

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

来自JLS

  

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

进一步

  

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

答案 1 :(得分:24)

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

逻辑上你要执行cancel(),然后返回 - 这就是你要说的。这两个动作(调用cancel()然后返回)在逻辑上是不同的。

现在,Java 可能"unit" type而不是void - 但这会影响返回值。

答案 2 :(得分:9)

就像写作:

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

所以,我认为void不是Java中的type

在C ++中,return cancel();是合法的。

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

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

答案 3 :(得分:6)

void不是一种类型。但是,如果您使用的是Void类型而不是void关键字,那么您的代码就可以使用,但是:您将在方法的所有退出点中手动拥有return null

答案 4 :(得分:5)

因为您没有返回 voidvoid不是值,因此无法返回。

答案 5 :(得分:4)

这是一个重言式。含义,void定义该方法没有返回值。因此,当无效的时候,你怎么能“返回空虚”呢?

答案 6 :(得分:3)

简答

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

长答案

JLS The *return* Statement section州:

  

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

JLS Method Return Type section声明:

  

方法的返回类型声明方法返回的值的类型,如果它返回值,或声明方法为void。具有返回类型R1的方法声明d1是返回类型 - 可替代另一个返回类型为R2的方法d2,当且仅当以下条件成立时:[...] *如果R1为空,则R2为空。

JLS Types, Values, and Variables chapter,第一段说明:

  

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

JLS The Kinds of Types and Values section声明:

  

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

现在再说几句话。 JLS Expression Statements section声明:

  

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

JLS Method Body section声明:

  

如果方法声明为void,则其主体不得包含任何具有Expression的return语句(第14.17节)。

最后,JLS Method Declarations section指出:

  

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

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

  • 如果return语句包含表达式,则表达式必须求值为有效值。
  • 有效的return表达式值必须是基本类型或引用类型。
  • void不是有效的值类型。
  • 使用void返回类型声明的方法,不返回任何值。
  • 方法void run()不会返回值。
  • run()return,没有表达式,我们很乐意将控制转移给来电者。
  • run()中,return some expression是一个错误,因为some expression必须是有效值,而run()不会返回值。

答案 7 :(得分:2)

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

严格来说,

void是一种类型的缺席,并且通过扩展,缺少一个值 - 所以返回一个没有意义,就像它一样没有意义(并且不允许)声明void变量。

答案 8 :(得分:1)

虚空不是真正的类型。 Void只是一个占位符,可以使方法定义的语法更加一致。这不是java的创新;这是继承自C.

即使方法return cancel()cancel(),编译器也不允许您编写void

答案 9 :(得分:1)

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

答案 10 :(得分:1)

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

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

答案 11 :(得分:1)

来自JLS:

  

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

...

  

带有Expression的return语句必须包含在方法中   声明为返回值或编译时的声明   发生错误。表达式必须表示某些变量或值   键入T,或发生编译时错误。类型T必须是可分配的   到方法的声明结果类型,或编译时错误   发生。

答案 12 :(得分:1)

Java grammar实际上并不关心方法调用的类型,所以这不是问题。在类型检查系统中,它必须是链条的更远处。我认为底线是如果在return关键字之后包含语法可选语句,那么系统需要传递一个值。 void当然类型,但没有类型void的值。

但是,当然,这些都不能解释你问题的答案。正如你所指出的那样,没有理由不允许这种习语。但也没有合理的理由允许它。所以这是一个折腾。人们可以试图理解为什么他们做了他们所做的事情,但这可能毫无意义。

答案 13 :(得分:0)

处理此问题的正确方法是:

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