为什么我在一个案例中“缺少退货声明”,而不是另一个案例?

时间:2016-06-22 15:04:01

标签: java

我正在编写一个代码,它将从文本文件中导入一串字符,使用堆栈分析字符串,并根据它是否符合某些规则来确定字符串所属的“语言”。为什么会出现这种情况:

public static boolean checkL2(File file) throws IOException
{
    Stack l2Stack = new Stack();
    boolean bStart = false;
    char w;

    Scanner sc = new Scanner(file).useDelimiter("\\s*");

    while(sc.hasNext()) //Load input from file onto stack
    {
        w = sc.next().charAt(0);

        if (w == 'A')
        {
            if (bStart == true)
            {
                return false;
            }
            else
            {
                l2Stack.push('A');
            }
        }
        if (w == 'B')
        {
            bStart = true;
            if (l2Stack.isEmpty() == true)
            {
                return false;
            }
            else
            {
                l2Stack.pop();
            }
        }
    }
    sc.close();
    if (l2Stack.isEmpty() == true)
    {
        return true;
    }

}

我收到一个错误,告诉我我错过了一个返回语句,但不是在这个中:

 public boolean isEmpty()
{
    if (top == -1) {
        return true;
    }
    else
    {
        return false;
    }
}

它们看起来和我非常相似,我无法弄清楚为什么一个工作正常而另一个没有。我希望第一位代码返回true或false,表示字符串是否符合规则A ^ nB ^ n。

8 个答案:

答案 0 :(得分:1)

它们并不相似 - 在第一个示例中,您可能永远不会返回值(仅当l2Stack.isEmpty()不为真或w == 'B' ...等)时,在第二个中您将始终返回

您应该添加一些默认值以返回,例如

    public static boolean checkL2(File file) throws IOException
    {
        ...

        if (l2Stack.isEmpty() == true)
        {
            return true;
        }

        //return default
        return false;
    }

如果布尔值不够,你应该返回一些其他类型,如某种Enum

答案 1 :(得分:1)

问题是您在return语句中总是if。如果某个方法的结果类型不是return,则必须 void。在您的情况下,您不能保证 if的任何都是真的,因此您不能保证会返回一个值。

答案 2 :(得分:1)

在您的热门方法中,您的代码可能无法点击任何if语句并且不返回任何内容。

如果l2Stack.isEmpty()为false,则代码没有return语句。考虑在此之后添加else语句以及代码应该执行的操作。

答案 3 :(得分:1)

编译时而言,编译器无法判断return是否在所有控制路径上都是显式的,因此会发出错误。

尽管你知道(可能)运行时行为是这样的,但事实并非如此。

(C和C ++允许这样做,给程序员带来了负担。但如果结果不是这样,这可能会导致问题,然后程序行为未定义。)

答案 4 :(得分:1)

正如其他答案已经提到的,之所以发生这种情况,是因为你声明你的函数返回一个布尔值,但是你可以执行你的函数而不需要实际返回一个return语句。例如,想象一下,如果你的代码更加明确,那么需要额外的回报:

    public static boolean checkL2(File file) throws IOException
    {
        Stack l2Stack = new Stack();
        boolean bStart = false;
        char w;

        Scanner sc = new Scanner(file).useDelimiter("\\s*");

        while(sc.hasNext()) //Load input from file onto stack
        {
            w = sc.next().charAt(0);

            if (w == 'A')
            {
                if (bStart == true)
                {
                    return false;
                }
                else
                {
                    l2Stack.push('A');
                }
            }
            if (w == 'B')
            {
                bStart = true;
                if (l2Stack.isEmpty() == true)
                {
                    return false;
                }
                else
                {
                    l2Stack.pop();
                }
            }
        }
        sc.close();
        if (l2Stack.isEmpty() == true)
        {
            return true;
        }
//Added return 
    return false;
    }

这个添加的返回是必要的,因为想象一下如果你的while循环结束时会发生什么,l2Stack.isEmpty() == false,在这种情况下你会到达“非void”函数的末尾而不返回Java不允许的任何东西。没有默认的返回操作,您必须在每种情况下明确声明要返回的内容。

答案 5 :(得分:0)

你必须在每种情况下都返回一些东西。

while(sc.hasNext()) //Load input from file onto stack
{
    w = sc.next().charAt(0);

    if (w == 'A')
    {
        if (bStart == true)
        {
            return false;
        }
        else
        {
            l2Stack.push('A');
            return true;
        }
    }
    else if (w == 'B')
    {
        bStart = true;
        if (l2Stack.isEmpty() == true)
        {
            return false;
        }
        else
        {
            l2Stack.pop();
            return true;
        }
    }
    else
    {
        return false;
    }
}

答案 6 :(得分:0)

当您在Java中编写将返回值(布尔值,字符串等)的方法时,编译器始终需要在第一次检查方法时找到返回值。例如,使用您的方法:

public boolean isEmpty()
{
    // The compiler can't be sure it will enter the if
    if (top == -1) {
        return true;
    }
    else{
        return false;
    }

    // Here is expecting a return statement
}

所以你只需要在方法的末尾添加一个return,这样编译器就可以确定它会返回一些东西(即使你确定它永远不会到达它)。

答案 7 :(得分:-1)

假设我有以下内容:

public int input(value) {
    if value > 10 {
        return value;
    } else {
        System.out.println("Value is not greater than 10.")
    }
 }

是否清楚如何通过代码获得不返回值的路径?任何分支或条件必须在每个代码路径中返回结果。它(至少)帮助可视化代码中的路径,并仔细检查每个可能路径中是否发生了返回。