Java 异常--层次结构、处理和抛出异常的介绍

220 阅读8分钟

Java在开发领域已经有很长一段时间了。尽管其他几种语言已经以更好的功能占领了市场,但Java仍将继续存在。

在学习Java的过程中,有很多东西需要了解,比如说Java的异常。Java中的异常是指在执行过程中破坏程序正常运行的事件。它可以在编译时或运行时发生,可以有很多类型。这些异常是不需要的,有一个基本的层次结构。

Java 异常层次结构的解释

Java-Exceptions-Hierarchy

Throwable类位于异常层次结构的顶端,其后是子类--Error和Exception。错误和异常不应该被混为一谈,因为这两个类之间存在着巨大的差异。

异常是程序中不需要的事件,可以在程序中处理,而错误不能在程序中处理,因为它是一种非常严重的情况,会对结构造成损害。

异常的例子。 IllegalArgumentException, ClassNotFoundException和NullPointerException。

错误的例子。InternalError, OutOfMemoryError和AssertionError。

异常有两种类型--检查的和未检查的异常。勾选的是编译时的异常,未勾选的是运行时的异常。RuntimeException的更多子类是未检查的,除此之外的是检查的。

让我们通过例子更好地了解Java的异常和错误。

在下面的例子中,方法 "print "递归地调用自己,直到达到Java线程的最大容量。在达到最大限度后,它以一个StackOverflowError退出。

public static void print(String myString) {

    print(myString);

}

Exception in thread “main” java.lang.StackOverflowError

at StackOverflowErrorExample.print(StackOverflowErrorExample.java:6)

这是一个错误,它没有在程序或代码中处理,因为它不能被调试。在这种情况下,代码或程序需要改变。

已检查和未检查的异常

Checked and unchecked exceptions

public void writeToFile() {

try (BufferedWriter bw = new BufferedWriter(new FileWriter(“myFile.txt”))) {

        bw.write(“Test”);

    } catch (IOException ioe) {

        ioe.printStackTrace();

    }

}

在上面的代码中,写在try块中的语句抛出了IOException。IOException是一个被检查过的异常,它在程序本身中被处理,异常堆栈跟踪被打印到控制台,如下图所示。

Exception in threadmainjava.lang.NullPointerException

    at IOExceptionExample.writeToFile(IOExceptionExample.java:10)

    at IOExceptionExample.main(IOExceptionExample.java:17)

在代码中不需要处理未被选中的异常,因此这里不处理NullPointerException,只处理IOException。

抛出Java异常

学习在Java中抛出异常与处理这些异常同样重要。这个功能可以帮助开发人员创建高质量的代码,使调试更容易。

抛出一个异常需要在代码中使用 "抛出 "语句。异常对象被提及,需要抛出一个消息。这个消息包含了关于异常的简介,如用户输入问题,任何服务器或后台相关的问题,等等。

下面是你如何抛出一个异常。

throw new Exception(“Exception message”);

Using the Throws keyword

throws关键字定义了该方法将抛出一个异常,一旦抛出异常,调用者就必须使用try-catch块来处理它。我们可以抛出有检查或无检查的异常。

throws关键字提供了关于该方法可能抛出的异常类型的信息,但并不能阻止程序被中止。

在下面的例子中,toString()方法调用了一个空引用,这是一个NullPointerException。

static void testMethod() throws Exception {

    String test = null;

    test.toString();

}

如何处理这个异常。

public class Example {

    public static void main(String[] arg) {

        try {

            testMethod();

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

异常类

开发者必须知道如何创建和抛出一个异常。这有助于更有效地使用异常。

异常类的定义是这样的--所有代表可恢复异常的类的超类。异常类的主要目标是扩展Throwable。构造函数描述了两个参数--on是详细的Message,提供了发生异常的消息细节,Throwable参数提供了异常的根本原因。

自定义异常

自定义异常基本上是为了给开发者提供更多的控制权,以便更好地向用户解释异常。Java中内置的异常可能没有提供足够的信息,所以开发者需要通过自定义异常来增加这些信息。如果异常发生在一个正在进行的程序中,用户需要知道它。自定义异常就是要提供更多的数据并使解释清晰。

那么,在Java中,开发者如何定制异常呢?最好的答案是通过扩展 java.lang.异常类,用一个新的类来扩展。这个新类需要一个父类的构造函数来容纳错误。

为了更好地理解自定义异常,这里有一个例子--假设有一个程序在连接到数据库时出现了问题,在这种情况下可以使用自定义异常。这个异常会有数据库的URL、用户名、密码等细节。而catch块可以有自定义的信息,并为用户提供一个简单的可读信息,说程序未能连接到数据库。

在Java中处理异常

Big-Data

Java中的异常处理对于保持程序的正常运行非常重要,即使是在发生意外事件的时候。如果不处理异常,它们将导致应用程序崩溃,从而使客户感到沮丧。如果使用重要用户数据的应用程序在用户工作时崩溃,会导致巨大的客户流失。应用程序的意外崩溃可能导致数据丢失。

为了避免这种情况,有必要进行异常处理。当用户一次又一次地输入错误的数据或在数据不正确的情况下,系统崩溃可能发生。在这些情况下,开发人员必须抛出一个异常,而不是让系统崩溃。

开发人员可以预测,一段Java代码可以抛出多少个异常。为了使程序顺利运行,最好的策略是明确地处理异常,并从不需要的事件中无缝恢复。有很多情况下,异常是无法预测的,这种异常被称为未处理的异常。也可以通过让开发人员检查代码质量和整个程序的适当可见性来跟踪这些异常,这样就可以避免这些异常。

追踪 Java 异常

开发人员知道,无论编码多么完美,所有的代码或程序集都会发生异常。因此,有一个程序可以通过在应用程序日志文件中保持记录来跟踪所有的Java异常。这个日志文件对当前的开发人员有很大的帮助,因为他们可以很容易地打开这个文件,跟踪程序所经历的所有异常情况。这种标准程序适用于小规模的应用程序,但不完全适用于大型企业软件。在大规模的应用程序中,跟踪错误的手动分析会导致轨道的丢失、不正确的分析和最终没有解决。因此,对错误监控软件的需求就出现了。该软件通过对重复的内容进行分类,并向开发人员报告最新错误的简要总结,从而减少了人工工作。这些自动化工具对精简数据非常有帮助,更容易理解。

对于小规模的应用程序,翻阅日志文件很容易。然而,企业应用程序每秒可以提供数千甚至数百万的请求。这使得人工分析过于繁琐,因为错误和它们的原因可能在噪音中丢失。这就是错误监控软件可以帮助的地方,它将重复的内容分组,并提供顶级和最近的Java错误的汇总视图。它们还可以捕捉和组织上下文数据,这比看日志更容易和更快。

捕捉特定的Java异常

也有一些特定的Java异常,开发人员可以在代码中捕捉。这涉及到一个专门的代码来恢复。例如,从REST API返回的一些Java错误是可以恢复的,但有些是完全不能恢复的,所以,为了捕捉可恢复的异常,你必须分别处理它们。

Try-catch方法是处理异常的最好方法。为了捕捉特定的Java异常,一个try块后面可以有一个或多个catch块,每个都指定一个特定的类型。如果在try块中有一个异常,那么这个异常就会被抛向第一个catch块,如果没有被这个类抓住,它就会被传递下去,直到被抓住或全部错过。

Try-Block

最后块

最后块是在每一种情况下都要执行的代码,无论是否有异常。这意味着final块每次都会被执行。

处理未捕获的或运行时的Java异常

未捕获的或运行时的异常可能在任何时候和任何代码中发生。开发者不会得到任何警告或信号,说明这些异常可能发生或不发生。Java提供了一个完美的方法来处理像这样的运行时异常。你可以在每个线程中设置一个未捕获异常处理程序,来捕获这种不可预测的异常。

总结

Java是一门庞大的语言,要成为一个专家,有很多事情是Java开发者 必须知道的。处理和抛出异常就是这样的功能,你应该把这些功能与程序结合起来,使程序和产生的应用程序对用户友好。以上的细节和信息很明显地表明,要想成为一名优秀的Java开发者,学习Java中的异常是很重要的,也是一个全新的课题。管理、跟踪和处理异常,很多时候都是一种挑战。你应该实时管理所有的异常,提高用户体验。