void run() {
...
if (done) return cancel();
...
}
其中cancel()
返回void
。这不会编译......我可以几乎理解为什么。但是如果我想从虚空中归还一个空洞,为什么不呢?相反,我最终写了这样的东西:
if (done) {
cancel();
return;
}
我不是在寻找代码风格的建议,我想知道为什么Java明确禁止这种类型的void返回。任何信息都表示赞赏,谢谢。
答案 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)
因为您没有返回 void
。 void
不是值,因此无法返回。
答案 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;
}
...
}