【问题标题】:Why isn't it unreachable?为什么不可达?
【发布时间】:2020-03-20 08:18:41
【问题描述】:
import java.util.Scanner;
import static java.lang.System.out;

public class practice
{
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        int x=sc.nextInt();

        try //outer try
        {
            try //inner try
            {
                if(x==1)
                    throw new NullPointerException();
                else if(x==2)
                    throw new InterruptedException();
                else
                    throw new RuntimeException();
            }
            catch(RuntimeException e) //catch block 1
            {
                out.println("RuntimeException caught!");
            }
            catch(InterruptedException e) //catch block 2
            {
                out.println("InterruptedException caught!");
            }
            out.println("inner try ends");
            return;
        }
        catch(Exception e) //catch block 3
        {
            out.println("Exception caught!");
        }
        finally
        {
            out.println("from finally");
        }

        out.println("main ends"); //unreachable code?
    }
}

在上面的代码中,异常总是从内部 try 块中抛出。 它要么是被catch block 1catch block 2 捕获的RuntimeException(未检查异常)或InterruptedException(已检查异常)。

任何生成的未经检查的异常(编译器无法预测)都将被catch block 1 捕获。因此,catch block 3 永远不会被执行。

此外,由于outer try 块中的return 语句,out.println("main ends"); 行也永远不会被执行。

我的解释是错误的,因为程序编译成功了。

谁能告诉我catch block 1out.println("main ends"); 行什么时候被执行?

【问题讨论】:

  • 在任何一种情况下都会抛出异常。并且您的 if-else 块对此负责
  • 如果out.println("inner try ends"); 抛出RuntimeException 会发生什么?
  • 你知道一定会发生异常并不意味着你的编译器知道
  • 另一个流行的例子:int x; for(int i = 0; i < 10; i++) { if(i == 0) x = 1; else x += 1; }。显然x 总是在这里初始化,但编译器并不知道。
  • @MadPhysicist 编译器在某些情况下知道。在简单的if...else 构造中,它可以确定x 是否被初始化。例如,int x; int i=0; if(i==0) x=1; else x=2; x+=1;

标签: java exception unreachable-code


【解决方案1】:

NullPointerExceptionRuntimeException 的子级。所以所有“内部尝试”块都以返回结束。

     out.println("inner try ends");
---> return;

所有 finally 块都按照docs 所说的那样执行:

finally 块总是在 try 块退出时执行。

在这种情况下,return 结束“外部尝试”,并执行 finally。

如果你让你的代码更简单,你会注意到最后的打印是不可达的:

public static void main(String args[]) {
    Scanner sc = new Scanner(System.in);
    int x = sc.nextInt();

    try {
        try {
            if (x == 1) {
                throw new NullPointerException();
            }
        } catch (NullPointerException e) {

        }

        return;
    } finally {
        out.println("from finally");
    }

    out.println("main ends");
}
Main.java:24: error: unreachable statement
    out.println("main ends");
    ^

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 2011-01-03
    • 2011-07-08
    • 2016-08-13
    相关资源
    最近更新 更多