java - java中什么时候应该使用异常

标签 java exception

我试图理解为什么要使用异常。 假设如果我有一个程序,

(不使用 try/catch)

public class ExceptionExample {

private static String str;

public static void main(String[] args) {
    System.out.println(str.length());
}

我遇到异常

Exception in thread "main" java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:22)

现在使用 try/catch,

public class ExceptionExample {

private static String str;

public static void main(String[] args) {
    try {
        System.out.println(str.length());
    } catch(NullPointerException npe) {
        npe.printStackTrace();
    }
}

}

我遇到异常,

java.lang.NullPointerException
at com.Hello.ExceptionExample.ExceptionExample.main(ExceptionExample.java:9)

现在我的问题是,

在这两种情况下,我都打印了相同的消息。那么使用try/catch有什么用呢?和

捕获异常后我们可以做什么,在本例中我已经打印了堆栈跟踪。 catch 仅用于打印跟踪或使用 getMessage() 或 getClass() 查找异常详细信息吗?

最佳答案

实际上,差异相当大。

获取第一个并在打印后添加一行:

public class ExceptionExample {

    private static String str;

    public static void main(String[] args) {
        System.out.println(str.length());
        System.out.println("Does this execute?");
    }
}

您将看到 Does thisexecute? 未打印,因为异常会中断代码流,并在未捕获异常时停止代码流。

另一方面:

public class ExceptionExample {

    private static String str;

    public static void main(String[] args) {
        try {
            System.out.println(str.length());
        } catch(NullPointerException npe) {
            npe.printStackTrace();
        }
        System.out.println("Does this execute?");
    }
}

将打印堆栈跟踪这会执行吗?。这是因为捕获异常就像在说:“我们将在这里处理这个问题并继续执行。”

还有一点,catch block 是应该发生错误恢复的地方,因此,如果发生错误但我们可以从中恢复,我们会将恢复代码放在那里。

编辑:

这是一些错误恢复的示例。假设我们在 C:\nonexistentfile.txt 处有一个不存在的文件。我们想尝试打开它,如果找不到它,则向用户显示一条消息,说明它丢失了。这可以通过捕获此处生成的 FileNotFoundException 来完成:

// Here, we declare "throws IOException" to say someone else needs to handle it
// In this particular case, IOException will only be thrown if an error occurs while reading the file
public static void printFileToConsole() throws IOException {
    File nonExistent = new File("C:/nonexistentfile.txt");
    Scanner scanner = null;
    try {
        Scanner scanner = new Scanner(nonExistent);
        while (scanner.hasNextLine()) {
            System.out.println(scanner.nextLine());
        }
    } catch (FileNotFoundException ex) {
        // The file wasn't found, show the user a message
        // Note use of "err" instead of "out", this is the error output
        System.err.println("File not found: " + nonExistent);
        // Here, we could recover by creating the file, for example
    } finally {
        if (scanner != null) {
            scanner.close();
        }
    }
}

这里有几点需要注意:

  1. 我们捕获FileNotFoundException并使用自定义错误消息而不是打印堆栈跟踪。我们的错误消息比打印堆栈跟踪更清晰、更用户友好。在 GUI 应用程序中,控制台甚至可能对用户不可见,因此这可能是向用户显示错误对话框的代码。文件不存在并不意味着我们必须停止执行代码。
  2. 我们在方法签名中声明抛出IOException,而不是与FileNotFoundException一起捕获它。在这种特殊情况下,如果我们无法读取该文件,即使该文件存在,也会抛出 IOException 异常。对于此方法,我们表示处理读取文件时遇到的错误不是我们的责任。这是一个如何声明不可恢复错误的示例(不可恢复,我的意思是这里不可恢复,它可能可以在更远的地方恢复,例如在调用 printFileToConsole 的方法中)。
  3. 我不小心在这里引入了 finally block ,所以我将解释它的作用。它保证如果 Scanner 打开并且在我们读取文件时发生错误,Scanner 将被关闭。这很重要,原因有很多,最值得注意的是,如果您不关闭它,Java 仍然会锁定该文件,因此您无法在不退出应用程序的情况下再次打开该文件。

关于java - java中什么时候应该使用异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12588552/

相关文章:

java - 控制异常输出格式

c# - 使用 Nunit 测试异常

java - tomcat Web 应用程序上的表情符号问题

c# - VS2010 没有在静态构造函数异常时中断调试

java - Android导航组件不断重新加载WebView

java - Java的Crystal report sdk在Ubuntu中不起作用

c# - Silverlight 3 WCF 服务 `CommunicationException` 服务器返回错误 : NotFound

c# - 使用锁并不能阻止 Collection 被修改;枚举操作可能无法执行

java - Jersey 测试相当于curl 请求

java - 重用同一个数组而不是声明一个新数组是否有意义?