在for循环中返回值

4

可能重复:
为什么会出现这个错误?

下面的三种方法完全相同,显然都返回 true。

然而,前两种编译通过,第三种却不行("missing return statement")。

语言规范的哪一部分决定了这种行为?

boolean returnTrue_1() { // returns true
    return true;
}

boolean returnTrue_2() { // returns true
    for (int i = 0; ; i++) { return true; }
}

boolean returnTrue_3() { // "missing return statement"
    for (int i = 0; i < 1; i++) { return true; }
}

如果可以的话,这个问题更具体,要求在JLS中提供参考。 - assylias
我猜是因为最后一个有一个条件。比如说,如果你设置i < -1,它就不会进入for循环,因此并不是所有路径都有返回值。而第二个则总是会发生。这只是我的猜测,但在我看来是有道理的。 - WozzeC
5个回答

4

为什么确定它可以正常完成? - assylias
1
我在想这是否更多地说明了如何决定“方法体能否正常完成”的问题。在某一点上,我们会遇到停机问题,但如果没有一个恰当的定义,则一些编译器可能会接受比其他更多的代码,这也不是好事。 - Thilo
1
如果我编写的Java编译器可以编译第三个样例(因为它非常聪明),那么这是否违反了规范呢? - Thilo
或者,如果我编写一个Java编译器,它更加“保守”,也不编译第二个呢? - Thilo
1
@Thilo 看看我的答案——它与可达性有关。你聪明的编译器和保守的编译器都会违反规格。 - assylias
显示剩余3条评论

3

这样的方法必须有一个保证被执行的返回语句,但在v3中并非如此。
有时候,通过人工智能你知道返回语句肯定会被调用,但编译器却不知道。


2
我猜问题是:JLS是否定义了编译器应该知道多少? - Thilo
@Thilo 可能这样的依赖图在 JLS 中描述起来太复杂了。因此,良好的编码实践是始终将返回语句作为最后一行。 - AlexWien

2
编译器遵循JLS 8.4.7,给出一个错误,因为它确定该方法可以正常完成:
如果一个方法声明了返回类型,那么如果方法体可以正常完成,则会在编译时出现错误。
为了确定方法是否可以正常完成,编译器需要确定for循环是否可以正常完成,这在JLS 14.21中定义:
基本的for语句可以正常完成,当且仅当以下至少一项为真:
- for语句可达,有条件表达式,并且条件表达式不是具有值true的常量表达式。 - 存在可到达的break语句退出for语句。
在第三种方法的情况下,存在一个条件表达式,它不是常量表达式,因为i不是final。因此,for语句可以正常完成,方法也可以作为结果完成。

证毕。


可以进一步思考JLS是否定义了“可达断点语句”。 - AlexWien
1
你还应该将这个答案提交到引发所有问题的原始问题中:http://stackoverflow.com/questions/14521547/why-does-this-get-error(即使它是你自己的答案,也可以接受它)。 - Thilo
@Thilo 我本来打算接受它,但是一个人必须等待两天才能接受自己的答案。关于原始问题,它更像是一个调试会话(可能应该被关闭为太局部化),而不是一个理论问题,所以我不确定这是否会对讨论有所帮助。 - assylias

0

具有某些返回类型的函数必须确保有返回语句。在任何条件块中的返回语句并不保证返回值。因此,您可能会收到警告。

但是,在情况3中,条件一开始就为false,所以您会收到错误提示。

尝试一些示例:

int abc1(){
    if(x>5)    // warning because return is possible but not assured.
    return x;
}

int abc2(){
x=0        
if(x>0)    // error because return is  not possible
return x;
}

int abc3(){        
if(x>0)    // no error no warning because return is  assured. 
return x;
else
return 1;
}

0
Java 确保如果方法有返回类型,则必须在任何情况下返回某些内容。如果 return 语句位于条件语句内部,则可能会执行,也可能不会执行。因此,您将不得不在 for 循环之外放置一个 return 语句才能使您的代码编译通过。在第二种情况下没有条件,所以没有问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接