有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是否显式向上抛出异常?

免责声明:我没有访问java编译器的权限,也无法安装IDE,我的工作区没有给我足够的权限

我试图理解Java是如何处理异常的,并偶然发现了这个问题:

如果一个子类在捕获所有异常的catch块中显式抛出异常,它会被抛出吗?例如,考虑下面的代码行:

public Class someClass  {
    public int value;
    public someClass()  {
        value = 1;
        try {
            value ++;
            if(value == 2)  {
                throw new Exception("value is 2");
            }
        }   catch   (exception e)   {
            System.out.println("I caught an exception.");
            throw new Exception("Does this exception get thrown upwards?");
            System.out.println("will this line of code get printed after the previously thrown exception?");
        }   finally {
            return;
        }
    }
}

public class anotherClass   {
    public static void main throws Exception{
        someClass someclass = new someClass();  // will this class catch the second explicitly thrown exception?
    }
}

因此,在try块中抛出一个新异常,由下面的catch块捕获。第二个throw语句在哪里?如果有调用类,它是否向上进入调用类?此外,即使println语句不在finally块中,也会在抛出异常后执行它吗

谢谢


共 (2) 个答案

  1. # 1 楼答案

    Where does the second throw statement go? Does it go upwards into the calling class if there is one?

    是的,异常将被抛出到调用方方法,在您的情况下,它是main()方法

    Will the println statement get executed after the exception is thrown even though it's not in the finally block?

    是的,System.out.println("I caught an exception.")将被执行,然后异常对象将被抛出给调用方(即,main()),因此在catch块中,下面的一行是不可访问的

    System.out.println("will this line of code get 
                  printed after the previously thrown exception?");
    

    重要的一点是,您可以始终使用exception.printStackTrace()(在catch块内)来检查异常是如何在方法堆栈中传播的。我建议您尝试一下,这样您就可以清楚地看到异常是如何在方法之间传播的

    我建议您参考here,并清楚地理解方法链是如何执行的

    另外,您可能感兴趣的另一点是,当main()方法抛出异常时(即main()本身或通过一个链,不管是什么情况),那么JVM会捕获异常并关闭

  2. # 2 楼答案

    虽然可能不是有意的,但在特定情况下会抛出异常而不是,您也可以通过someClass的构造函数中缺少的throws子句看到这一点

    原因是finally块中的return语句,导致java放弃异常(一个好的IDE会给你一个“最终块不能正常完成”的警告)

    更具体地说,section 14.20.2 of the specification指出:

    If the catch block completes abruptly for reason R, then the finally block is executed. Then there is a choice:

    • If the finally block completes normally, then the try statement completes abruptly for reason R.

    • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

    其中,原因Sreturn语句,原因Rthrow new Exception("Does this exception get thrown upwards?");

    你可以看到自己on ideone.com

    class someClass {
        public int value;
    
        public someClass() {
            value = 1;
            try {
                value++;
                if (value == 2) {
                    throw new Exception("value is 2");
                }
            } catch (Exception e) {
                System.out.println("I caught an exception.");
                throw new Exception("Does this exception get thrown upwards?");
            } finally {
                return;
            }
        }
    }
    
    class anotherClass {
        public static void main(String[] args) {
            try {
                someClass someclass = new someClass(); 
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    输出:

    I caught an exception.
    

    但就这个问题而言,贾瓦盖的回答已经足够全面地涵盖了这一点