Java循环编译错误

谁可以给我解释一下这个? 首先,我知道为什么这个代码

String getName(){
    for(;;){}
}

将违反return类型的方法:它是无限的,但为什么这个代码需要最终的返回值

String getName(){
    for(;i < limit; i++){// i is already defined
        if(someArrayList.get(i).isDead)
            continue;
        return someArrayList.get(i).name;
    }
    //needs a final return
}

返回值存在于循环中并返回getName()方法的值,那么原因是什么? 另一篇文章提出,如果环路对我的病情是负面的,那么我就这样重写它:

String getName(){
    for(; i < 10; i++){// i is already defined
        if((i+1) == limit){
            if(!someArrayList.get(i).isDead)
                return "";
        }else{
            if(someArrayList.get(i).isDead)
                continue;
            return someArrayList.get(i).name;
        }
    }
    // needs a final return
}

同样的编译时错误,即使我重新定义了i在for循环的条件,到0 ,所以我i变为零,如果内部条件检查出负我处理它自己。 总而言之,如果我将它嵌入无限循环中,那没关系。

String getName(){
    for(;;){
        for(; i < limit; i++){// i is already defined
            if(someArrayList.get(i).isDead)
                continue;
            return someArrayList.get(i).name;
        }
    }
}

是因为它有一个范围吗? 因为我觉得它涵盖了所有场景,我只想知道为什么,在我添加最后的return和生活的美好之前

最后这工作正常:

String getName(){
    for(;;){
        for(; i < limit; i++){// i is already defined
            if(someArrayList.get(i).isDead)
                continue;
            return someArrayList.get(i).name;
        }
        return "";
    }
}

斯威特先生说这种类型的代码在java中是可以的


你需要一个最终的return语句,因为你的列表可能只包含'dead'条目,在这种情况下你的程序将达到'limit'并退出for循环。

我在这里看到了评论,所以需要澄清。 编译器根本无法分析所有潜在的结果,并且100%肯定地决定该循环是否会达到其自然结束。 这在理论上是不可能的(你可以阅读关于停止问题的更多信息)。

虽然编译器有时可以解决这个问题,但通常只会尝试在相对简单的情况下执行此操作。 其背后的原因很简单 - 如果你的代码足够复杂,以至于不清楚循环是否结束 - 它会混淆人类读者,他们不明白为什么在循环之后没有返回语句。 这样的代码是不好的代码。


因为你可以打破循环。 通常你必须返回一些东西,这就是预期会发生的事情。 编译器不是魔术师,不能说明你的循环条件是否无限(至少在大多数情况下),通常它是依赖于运行时间的。


NP硬

简短的版本,你要求计算机做的不只是复杂或困难,但很难有一个特殊的名词NP Hard,并且在Stack Overflow有相当好的报道,参见'NP Hard vs NP Complete',或者关于证明暂停问题的这个问题是NP Hard,或者关于数学堆栈溢出的这个问题,最后但并非最不重要的一点,请参阅维基百科NP Hard的一般定义。 编译器不信任一个条件块,并希望那里有一条不依赖于该条件块的返回语句的路径。

图灵的诅咒

长版本,当编译器通过代码评估路径时,它会创建一个称为格的结构来跟踪通过该方法的所有不同路径。 在方法需要返回值的情况下,编译器通过从方法出口点开始使用格并检查所有向后寻找返回值的路径。 是的,你的循环有一个返回语句,但是编译器不能预先知道你的条件块总是会退出,所以它在查找返回值时忽略该块。

看到实际解决你的一些例子的暂停问题,但确保你检查这个答案,这是我最喜欢的答案,只是因为它的魅力。 你声称编译器应该能够告诉循环将退出,如果要编译编译器来寻找那些特定的代码习惯用法,这是有好处的; 但是这就是问题所在,如果试图编译一个膨胀的编译器,就有太多特殊情况需要编写代码。 因此,它在查找返回值的路径时推广该案例并忽略条件块。

Jon Skeet说过的方法中有多个出口点是可以的,他没有说在条件块内只有一个出口点是可以的。

你有看到下面的代码版本的原因,它提供了返回值的默认路径,这只是提供它的一种方式。

String getName(){

    // default return value
    String retVal = "";

    for(;i < limit; i++){// i is already defined
        if(someArrayList.get(i).isDead)
            continue;
        return someArrayList.get(i).name;
    }

    //needs a final return
    return retVal;
}

当你提到下面的代码时,

将违反返回类型的方法:它是无限的,但为什么这个代码需要最终的返回值?

String getName(){
    for(;;){}
}

我会指出,代码需要在方法声明中定义一个返回值,所以下面的代码不会导致编译错误

void getName(){
    for(;;){}
}

这个问题又回到你身上,因为为什么你坚持要声明一个方法必须返回一些东西,同时还坚持只使用受条件块限制的结构,以便编译器不能检测到它们总是会执行。

我对你的问题是为什么你不只是使用默认的返回值,有没有什么原因你似乎在避免这种方法? 这对我来说并不重要,但它有助于了解您是否有像编码标准这样的实用挑战,或者它是否更像哲学反对意见。

链接地址: http://www.djcxy.com/p/39985.html

上一篇: Java loops compile errors

下一篇: Distinct sub sequences summing to given number in an array