Java可以识别无限循环吗?

2022-09-01 17:12:11

给定以下代码示例:

public class WeirdStuff {

    public static int doSomething() {
        while(true);
    }

    public static void main(String[] args) {
        doSomething();
    }
}

这是一个有效的Java程序,尽管方法doSomething()应该返回int,但永远不会。如果运行它,它将以无限循环结束。如果将 while 循环的参数放在单独的变量中(例如布尔 bool = true),编译器会告诉您在此方法中返回 int。

所以我的问题是:这是否在Java规范中的某个地方,是否存在这种行为可能有用的情况?


答案 1

我只引用Java语言规范,因为它对此非常清楚:

本节专门对“可访问”一词进行精确解释。这个想法是,从构造函数,方法,实例初始值设定项或包含语句的静态初始值设定项的开头到语句本身,必须存在一些可能的执行路径。分析考虑了报表的结构。除了对 while、do 和条件表达式具有常量值 true 的语句的特殊处理外,在流分析中不考虑表达式的值。

...

while 语句可以正常完成,但至少存在以下一项为真:

  • while 语句是可访问的,条件表达式不是值为 true 的常量表达式。
  • 有一个可访问的中断语句退出 while 语句。

...

非空块中不是开关块的所有其他语句 S 都可以访问,因为 S 前面的语句可以正常完成。

然后应用上述定义:

如果将方法声明为具有返回类型,则其主体中的每个返回语句 (§14.17) 都必须具有表达式。如果方法主体可以正常完成,则会发生编译时错误 (§14.1)。

换句话说,具有返回类型的方法必须仅使用提供值返回的 return 语句进行返回。它不允许“从身体的末端掉下来”。

请注意,方法可能具有声明的返回类型,但不包含任何返回语句。下面是一个示例:

class DizzyDean {
  int pitch() { throw new RuntimeException("90 mph?!"); }
}

答案 2

Java规范定义了一个名为“无法访问的语句”的概念。不允许在代码中使用无法访问的语句(这是编译时错误)。根据定义,语句使以下语句无法访问。在Java中,您甚至不允许在语句之后有语句。请注意,虽然停止问题在一般情况下是不可判定的,但无法访问语句的定义比仅仅停止更严格。它决定了程序绝对不会停止的非常具体的情况。从理论上讲,编译器无法检测所有无限循环和无法访问的语句,但它必须检测规范中定义的特定情况。while(true);returnwhile(true);


推荐