Java 为什么这段代码有一个丢失的return语句错误?
如果我将这段代码的else-If部分更改为else语句,它将毫无问题地运行,因此我知道如何使它运行。我有点困惑的是,为什么在返回语句处于当前形式时会出现缺失的返回语句错误。我的返回取决于布尔变量负值的值。我涵盖了真实和错误的状态,这不足以涵盖一切吗 或者,我总是必须在else中有一个return语句,或者在函数的底部添加一个无意义的return true,编译器才能接受我的代码,因为它涵盖了所有情况Java 为什么这段代码有一个丢失的return语句错误?,java,Java,如果我将这段代码的else-If部分更改为else语句,它将毫无问题地运行,因此我知道如何使它运行。我有点困惑的是,为什么在返回语句处于当前形式时会出现缺失的返回语句错误。我的返回取决于布尔变量负值的值。我涵盖了真实和错误的状态,这不足以涵盖一切吗 或者,我总是必须在else中有一个return语句,或者在函数的底部添加一个无意义的return true,编译器才能接受我的代码,因为它涵盖了所有情况 import java.util.*; import java.lang.*; import j
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
else if (negative) {
return (a < 0 && b < 0);
}
}
public static void main (String[] args) throws java.lang.Exception
{
}
}
import java.util.*;
导入java.lang.*;
导入java.io.*;
表意文字
{
公共布尔posNeg(整数a、整数b、布尔负){
如果(!负){
返回(a<0&&b>0)| |(a>0&&b<0);
}
否则,如果(否定){
返回(a<0&&b<0);
}
}
公共静态void main(字符串[]args)引发java.lang.Exception
{
}
}
如果
=>如果
=>如果
=>其他
条件在哪里
对于return语句,必须处理所有分支(条件)。
你可以做:
if (!negative)
return (a < 0 && b > 0) || (a > 0 && b < 0);
return (a < 0 && b < 0);
如果(!负)
返回(a<0&&b>0)| |(a>0&&b<0);
返回(a<0&&b<0);
或:
如果(!负)
返回(a<0&&b>0)| |(a>0&&b<0)
其他的
返回(a<0&&b<0);
或者(我喜欢的方式):
返回负数?(a<0&&b<0):(a<0&&b>0 | a>0&&b<0)
然而,我建议避免这种消极的情况,在复杂的场景中,对人脑来说更难。甚至像IntelliJ这样的Java IDE也可以帮助找到这些模式来修复它们。你最终会得到:
if (negative)
return (a < 0 && b < 0);
else
return (a < 0 && b > 0) || (a > 0 && b < 0);
if(否定)
返回(a<0&&b<0);
其他的
返回(a<0&&b>0)| |(a>0&&b<0);
当编译器看到else if
没有else
或后面的返回语句时,无法确定所有控制路径都将指向有效的返回语句
编译器有时可能是智能的,但在这种情况下它不可能是智能的(也不应该是)
这种行为在您的示例中很有用:在这种情况下,您完全没有理由使用else if
。简单的else
更容易阅读,更简洁,更不容易出错
在这种情况下,else
非常有表现力。它的意思是“与if子句相反”,如果将来代码发生变化,这种情况仍然存在
如果编译器允许,您当前的代码更有可能包含和/或引入错误
下面是我将如何重写方法体:
if (negative) {
return (a < 0 && b < 0);
}
else {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
if(否定){
返回(a<0&&b<0);
}
否则{
返回(a<0&&b>0)| |(a>0&&b<0);
}
一般来说,你应该更喜欢if(negative)
而不是if(!negative)
,除非有令人信服的理由(即可读性)这样做
另外,很多人(包括我自己)都试图在if/else语句中把最简单的子句放在第一位。使代码易于阅读是一件好事
请查看StephenC的答案,以获得技术解释和有关编译器为何以这种方式运行的更多背景信息 您不需要在“else”大括号中使用“if(negative){}”我想您已经知道第二个if是多余的
if(negative)
被解释为上下文无关,这意味着编译器忽略了已经处理过的if(!negative)
。其他问题从直观的角度解释了错误消息的含义。然而,“编译器是聪明的,但不是完美的!”的评论没有抓住要点
事实上,Java编译器将您的示例称为错误,因为Java语言规范要求它将其称为错误。不允许Java编译器在这方面“聪明”
以下是JLS(适用于Java71)的实际说明,以及它如何应用于错误示例的简化版本,然后应用于更正版本 “如果某个方法被声明为具有返回类型,则如果该方法的主体可以正常完成(),则会发生编译时错误。换句话说,具有返回类型的方法只能通过使用提供值返回的return语句来返回;不允许“从其主体的末尾删除”。” (阅读“正常完成”的定义…) 决定“正常”完成是否可能的规则是中的可达性规则。他们说:
public int test(boolean a) {
if (a) {
return 1;
}
else if (!a) {
return 0;
}
}
在本例中,else语句是一个if-then语句,它可以按照规则#1正常完成。因此,根据规则#2,if-then-else语句也可以正常完成。但这是一个编译错误,因为它表示具有返回类型的方法无法正常完成
但是如果你把这个例子改成这个
public int test(boolean a) {
if (a) {
return 1;
}
else {
return 0;
}
}
现在根据规则#3,if语句和else语句都不能正常完成。因此,根据规则2,整个if-then-else无法正常完成。这就是……所要求的。。。因此没有编译错误
1-Java 8 JLS基本上会说相同的话,尽管节号可能不同…您的所有分支都应该有一个返回
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
else if (negative) {
return (a < 0 && b < 0);
}
}
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
return (a < 0 && b < 0);
}
public boolean posNeg(int a,int b,boolean negative){
如果(!负){
返回(a<0&&b>0)| |(a>0&&b<0);
}
否则,如果(否定){
返回(a<0
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
else if (negative) {
return (a < 0 && b < 0);
}
}
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
else {
return (a < 0 && b < 0);
}
}
public boolean posNeg(int a, int b, boolean negative) {
if (!negative) {
return (a < 0 && b > 0) || (a > 0 && b < 0);
}
return (a < 0 && b < 0);
}
public boolean posNeg(int a, int b, boolean negative) {
return ((negative) && (a < 0 && b < 0)) || ((!negative) && (a < 0 && b > 0) || (a > 0 && b < 0));
}
public boolean posNeg(int a, int b, boolean negative) {
return ((negative) && (a < 0 && b < 0)) || ((!negative) && ((a < 0) == (b > 0)));
}