【问题标题】:Is there any other role of throws instead of propagating a checked Exception?除了传播检查的异常之外,还有其他的 throws 角色吗?
【发布时间】:2015-07-14 22:36:20
【问题描述】:

在对Exception Handling中的throws声明进行了越来越多的研究之后,我感到困惑。我发现-

如果一个方法能够引起它不会的异常 句柄,它必须指定此行为,以便方法的调用者 可以保护自己免受该异常的影响。

class Boxing1{  
public static void main(String args[]) throws IOException{
    new B().meth2();
    System.out.println("33333333");
}
}
class A{

    void meth1() throws IOException{
        throw new IOException();
        //throw new NullPointerException();
        //System.out.println("111111111111");
    }
}
class B{
    void meth2() throws IOException{
        new A().meth1();
        System.out.println("2222222");
    }
}

除了使用 throws 之外,仍然存在异常-我的控制台显示以下错误-

Exception in thread "main" java.io.IOException
    at A.meth1(Boxing1.java:17)
    at B.meth2(Boxing1.java:24)
    at Boxing1.main(Boxing1.java:10)

直到我没有在 try-catch 块中调用 meth1 之前,尽管使用了 throws,但还是会出现异常。 throws在这里的作用是什么?

try{new A().meth1();}catch(Exception e){System.out.println(e);}

我需要你的确认。我很困惑。我的一行查询是-

除了传播CheckedException,还有throws 的其他角色吗?

【问题讨论】:

  • 您也可以添加throws SomeRuntimeException。它对编译器来说是多余的,但作为文档很有用。
  • 为什么你认为它可能会做其他事情?你读过这方面的东西吗?或以不同的方式问...您为什么感到困惑?你有没有发现关于throws的描述有矛盾?
  • 你上面的陈述几乎是正确的——“它是为了告诉调用类有可能在这里发生这个异常,我现在不处理它。你会小心的。”
  • @dubey-theHarcortians 对此有何困惑?这和你在问题中写的一样,所以我仍然不知道你的问题是什么。
  • “不使用 throws 仍然存在异常” main 方法应该将其异常传播到哪个方法?它的“上方”没有任何东西可以处理该异常,因此它仍然未处理。

标签: java exception-handling propagation throws checked-exceptions


【解决方案1】:

让我们诊断一下:

首先你的程序会因为代码抛出异常

throw new IOException();

当你放一个try catch块时,异常会在catch块中处理。

请记住,有两种类型的异常:已检查和未检查的异常,然后是错误

throw 关键字只是引发异常(也可以是自定义异常!!!)并暂停执行(如果没有使用 catch 处理异常)

一般做法:

  • catch 块将处理异常
  • Throws 会将错误传递给调用者,但没有恢复机制。

【讨论】:

  • 我只寻找是或否作为答案。仅描述是否存在抛出的任何其他角色而不是传播检查的异常。
  • @bvdb 向您解释。它关于实施的角度。投掷选中或未选中的东西,或者您可以将其用于自己的用途。也许你应该尝试一些现实生活场景。
  • 我在很多文档中研究过——Java throws关键字是用来声明异常的,是什么意思?
  • 我会给你一个例子......你想复制粘贴一个文本文件到另一个位置......你写了一个程序来完成这项工作......但是由于人为错误你输入了拼写错误的名字的文本文件...或您的程序正在寻找的文件不存在...在这种情况下,您的程序需要处理这种情况...。异常是一种警报机制,可以查明问题的原因
【解决方案2】:

如你所说,有两种例外。

  • “已检查异常”需要开发者注意。当您使用抛出已检查异常的方法(即IOException)时,您需要处理它(即捕获)或传播给调用者(即抛出)假设调用者会捕获它。

  • “未经检查的异常”不需要特别注意。这些是NullPointerException 之类的异常,错误。 您不想编写代码来掩盖潜在的错误。不可能涵盖所有内容。不过,如果您想捕获未经检查的异常,您可以。

  • 注意:还有一些其他的可投掷物体。您可以抛出所有扩展 Throwable 类的对象。但是你不应该在你的代码中使用这个功能。这确实适用于系统错误和断言。

如果您抛出已检查异常,则您需要通过在方法签名中指定 throws SomeException 来警告开发人员。对于未经检查的异常,您不需要。

编译器会检查这一点。它很容易识别未经检查的异常,因为未经检查的异常扩展了RuntimeException 类。

最后,在您的情况下,您将异常一直传播到顶部,到您的 main() 方法。即使在那里你继续传播它。在这种情况下,JVM 只会打印它。

【讨论】:

  • 我只寻找是或否作为答案。仅描述是否存在抛出的任何其他角色而不是传播已检查的异常。
  • 没有其他角色。它只是传播异常。但是您不能只将它用于已检查的异常,也可用于未检查的异常(但它不是强制性的)和错误(这是Throwable 的单独类)。错误通常是您不想涵盖的操作系统错误。
  • 我在很多文档中研究过——Java throws关键字是用来声明异常的,是什么意思?
  • @dubey-theHarcortians 这只是意味着您指定方法可以创建哪些异常。然后,当您(或其他开发人员)想要使用此方法时,他只需查看方法的标头即可了解它可能导致哪些异常。 (例如,如果您编写了一个方法openFile 试图打开一个文本文件。您知道该文件并不总是存在,因此您的代码可能会导致FileNotFoundException。在这种情况下,只需将throws FileNotFoundException 放在您的方法后面签名。喜欢:public void openFile(String filename) throws FileNotFoundException { ... }
【解决方案3】:

我认为异常处理是非常合乎逻辑的并且抛出是必要的,因为您并不总是希望在可能发生的级别上处理异常。

假设您有一个管理多个文件中存在的值的对象

public class MultipleFileManager {
    private List<String> filesContent;
    .
    . 
    .
    public void addFileContent(String filename) {
        File file = new File(filename);
        try {
            FileReader fr = new FileReader(file);
            .
            //adding filecontent to filesContent list
            .
        } catch (IOException e) {
            System.err.println("file not added");
        }
    }
}

在此示例中,您显然希望在 MultipleFileManager 级别处理异常,因为如果仅一个损坏的文件可能会使整个线程崩溃,那将是非常错误的。

因此,FileReader 类方法中的 throws IOException 语句告诉您,您将在 addFileContent() 级别处理异常,否则如果遇到损坏的文件,您就有可能使整个线程崩溃,在该线程中抛出异常。

如果这个线程是主线程,整个应用程序就会崩溃。

【讨论】:

  • “否则您可能会导致整个应用程序崩溃” ...您的意思是“或者您可能会导致当前线程崩溃”。如果当前线程是“主”线程,那么它将使应用程序崩溃,但如果不是,那么该线程就会死掉。
  • 感谢您发现错误和澄清,我将编辑答案
猜你喜欢
  • 2023-01-03
  • 2015-12-08
  • 1970-01-01
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
相关资源
最近更新 更多