当main方法抛出异常时,它意味着什么?

问题描述 投票:28回答:7

我正在审查我为明天上午的期末考试做准备的期中考试。我错了这个问题,但是没有正确的答案指出,我忽略了向教授询问它。

请考虑以下代码段:

public static void main(String[] args) throws FileNotFoundException

关于此代码的以下哪些陈述是正确的?

  1. main方法旨在捕获和处理所有类型的异常。
  2. 主要方法旨在捕捉和处理FileNotFoundException
  3. 如果发生FileNotFoundException,主要方法应该简单地终止。
  4. 如果发生任何异常,主要方法应该简单地终止。

我选择了第二个选项。

java exception
7个回答
17
投票

答案是4号,

4.-如果发生任何异常,主要方法应该简单地终止。

throws子句仅声明该方法抛出已检查的FileNotFoundException,并且调用方法应捕获或重新抛出它。如果在main方法中抛出(而不是catch)未检查的异常,它也将终止。

检查此测试:

public class ExceptionThrownTest {

    @Test
    public void testingExceptions() {

        try {
            ExceptionThrownTest.main(new String[] {});
        } catch (Throwable e) {
            assertTrue(e instanceof RuntimeException);
        }

    }

    public static void main(String[] args) throws FileNotFoundException {

        dangerousMethod();

        // Won't be executed because RuntimeException thrown
        unreachableMethod();

    }

    private static void dangerousMethod() {
        throw new RuntimeException();
    }

    private static void unreachableMethod() {
        System.out.println("Won't execute");
    }
}

正如你所看到的,如果我抛出一个RuntimeException,即使抛出的异常不是FileNotFoundException,该方法也会终止


10
投票

老兄,有点晚了,但回答是3号。

数字1为false,因为它没有处理FileNotFoundException

由于同样的原因,数字2是错误的。

3号是真的。如果抛出FileNotFoundException,则main方法将终止。

4号是假的。如果出现任何异常,它不会终止。它仅在未经检查的异常或FileNotFoundException的情况下终止。如果'throws'子句中没有声明其他已检查的异常,则表示它们正在该方法中处理。


3
投票

main方法没有捕获任何异常,而是通过将FileNotFoundException抛给调用main方法的源来处理throws

系统运行时启动JVM类,JVM类中的一个特定类调用main方法。

在这种情况下,主方法的Java language specification的处理受JVM类的支配。

  • 您可以在Oracle提供的OpenJdk中阅读它。
  • 另外,您可以查看那里可用的一些JVM的源代码,然后通过该路径将您带到其他编程语言main()

我想在这个话题中分享我的小谦卑的研究外壳,希望它有助于好奇的:)


2
投票

我同意其他一些答案,即问题的正确答案是选项3.选项4说:

  1. 如果发生任何异常,主要方法应该简单地终止。

请注意此选项中的“任何”。以下是发生异常的代码示例,但public static void main(String[] args) throws FileNotFoundException { try { methodThatThrowsACheckedException(); } catch (SomeCheckedException e) { // do something to handle this exception } } 不会终止:

UncheckedException

在此代码中发生异常,但该方法不会终止,因为它已设置为处理此异常。如果例外是未被捕获的FileNotFoundException,那么该方法当然会终止。但是,选项4的要点是,任何反例都会使它失效,因为它表示发生了“任何”异常。

但是,选项3将此终止限制为仅在抛出方法签名中的异常时发生:

  1. 如果发生public static void main(String[] args) throws FileNotFoundException { try { methodThatThrowsFileNotFoundException(); } catch (FileNotFoundException e) { // do something to handle this exception } } ,主要方法应该简单地终止。

选项3更有意义的原因是因为以下代码在实践中没有意义:

main()

声明一个方法抛出一个异常,但是在方法中捕获该异常没有多大意义(除非你在做某事之后重新抛出它,在这种情况下,选项3仍然存在,因为该方法最终终止)。


0
投票

只有FileNotFoundException的声明,不可能说哪个答案是客观正确的。任何陈述都可能是真的,具体取决于方法的定义。

  1. main方法旨在捕获和处理所有类型的异常。
  2. 主要方法旨在捕捉和处理public static void main(String[] args) throws FileNotFoundException { while (true) { try { doSomething(); } catch (Exception e) {} } }

上述两种说法都适用于以下情况:

main()

FileNotFoundException从不抛出声明的异常,但这不是错误;只是毫无意义和误导。

  1. 如果发生public static void main(String[] args) throws FileNotFoundException { try { doSomething(); } catch (Exception e) { return; } } ,主要方法应该简单地终止。
  2. 如果发生任何异常,主要方法应该简单地终止。

上述两种说法都适用于以下情况:

FileNotFoundException

当然,我们可以根据一个体面和合理的程序员打算与此方法签名进行通信的内容来猜测问题的意图。这将是他们打算抛出Exception的方法,并且必须处理其他检查的returns。我们还可以合理地假设“句柄”不仅仅意味着“过程”,而且具体地说它不会(重新)抛出这样的异常。

这些假设立即排除了#1和#2。

剩下的问题是“简单终止”是否包括抛出异常,或者只是一个明确的System.exit() / public static void main(String[] args) throws FileNotFoundException { try { doSomething(); } catch (FileNotFoundException fnfe) { throw fnfe; } catch (Exception e) { return; } } 。在前一种情况下,#3和#4都可能仍然是真的:

main()

在后一种情况下,#3和#4都不是真的,同时也满足FileNotFoundException将抛出FileNotFoundException的假设。


总而言之,这些选择措辞并不好。如果我必须选择答案,那么基于MartinV答案的逻辑将是#3。我的假设是,#3中的“应该”这个词是教授的不幸选择,而“可能”之类的东西本来是更好的选择。使用比“简单终止”(并且可以说是“处理”)更精确的语言也是一个好主意。


-1
投票

虽然已经为这个问题选择了答案,但我认为你的测试的正确答案是3号:

  1. 如果发生FileNotFoundException,主要方法应该简单地终止。

因为它说应该,不会。 我的意思是,该方法中的代码可以捕获任何异常,包括已检查和未检查,以及吞咽,恢复或重新抛出它 - 或者它根本无法捕获它们。

但是如果它在没有最终(重新)抛出它的情况下捕获main(),它就会破坏它自己的契约:任何调用者都不会看到方法签名中所述的异常,因为该方法处理它(甚至编译器可能会抱怨它案例,说永远不会抛出异常,但我不确定这里)。

我认为你的中期问题是关于设计的问题而不是具体的实施。


-1
投票

答案是2和3。

2. main方法旨在捕获和处理FileNotFoundException。 3.如果发生FileNotFoundException,主方法应该简单地终止。

但是如果它无法处理异常,即使它被设计为处理它并且程序异常终止。

throws关键字用于使JVM处理我们懒惰处理的异常,它成功编译但在运行时显示异常(如果你在main方法中处理它然后编译并成功运行)。

4.如果发生任何异常,主要方法应该简单地终止。不正确总是因为发生的异常可能在main方法中处理。

1. main方法用于捕获和处理所有类型的异常。这是不正确的,因为JVM不处理未经检查的异常。


-1
投票
  1. FileNotFoundException最终抛出所有未处理的异常,对吧?所以,有效地添加投掷throws是多余的。
  2. main()语句不暗示方法如何处理异常。这个FileNotFoundException方法确实可以处理throws,然后重新抛出它。

因此,qazxswpoi语句没有说明如何捕获和处理任何异常。问题3和4只有在我们假设有问题的例子没有得到处理时才有效。没有这种假设,问题是不确定的。有了这个假设,3和4都是真的!

正确答案是要求学校退还此课程 - 即使是6。5年后。

你能转发这位老师的联系方式吗?我想和他们谈谈。

© www.soinside.com 2019 - 2024. All rights reserved.