回首Java——关于java异常

来源:互联网 发布:网络语言排面什么意思 编辑:程序博客网 时间:2024/05/01 00:03

异常继承图

在java中,异常分为检查异常和非检查异常,它们都在异常结构图中,下面的这个图展示了java异常层次结构图

image

从上面的图我们可以看到:程序的异常Throwable分为两类

  • 程序的异常:Throwable
    • 严重问题:Error 我们不处理。这种问题一般都是很严重的,比如说内存溢出。
    • 问题:Exception
      • 编译期问题:不是RuntimeException的异常 必须进行处理的,因为你不处理,编译就不能通过。
      • 运行期问题:RuntimeException 这种问题我们也不处理,因为是你的问题,而且这个问题出现肯定是我们的代码不够严谨,需要修正代码的。

红色的是检查异常,在方法中抛出的任何检查异常都必须在方法的抛出子句中捕获或声明。检查异常必须在编译时捕获。之所以叫做检查异常,那是因为无论是java编译器或是java虚拟机都检查以确保服从该规则。绿色的是非检查异常,它们是不希望恢复的异常,如空指针、除以0等。

如何程序出现了问题,我们没有做任何处理,最终jvm会做出默认的处理。
把异常的名称,原因及出现的问题等信息输出在控制台。

  • JVM的默认处理方案

把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
程序停止执行


Throwable

在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出)。Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性。

Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类。

Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,Java虚拟机运行错误(Virtual MachineError),当 JVM 不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。

这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查 的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。

Exception(异常):是程序本身可以处理的异常。

Exception 类有一个重要的子类 RuntimeException。RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。

注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。

通常,Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。

可查异常(编译器要求必须处置的异常):正确的程序在运行中,很容易出现的、情理可容的异常状况。可查异常虽然是异常状况,但在一定程度上它的发生是可以预计的,而且一旦发生这种异常状况,就必须采取某种方式进行处理。

除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。

不可查异常(编译器不要求强制处置的异常):包括运行时异常(RuntimeException与其子类)和错误(Error)。

Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。

运行时异常:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。

运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。

非运行时异常 (编译异常):是RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

  • getMessage():获取异常信息,返回字符串。
  • toString():获取异常类名和异常信息,返回字符串。
  • printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
  • printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。

Java常见异常

在Java中提供了一些异常用来描述经常发生的错误,对于这些异常,有的需要程序员进行捕获处理或声明抛出,有的是由Java虚拟机自动进行捕获处理。Java中常见的异常类:

  • runtimeException子类:

    1、 java.lang.ArrayIndexOutOfBoundsException

    数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。

    2、java.lang.ArithmeticException

    算术条件异常。譬如:整数除零等。

    3、java.lang.NullPointerException

    空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等

    4、java.lang.ClassNotFoundException

    找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

    5、java.lang.NegativeArraySizeException 数组长度为负异常

    6、java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常

    7、java.lang.SecurityException 安全性异常

    8、java.lang.IllegalArgumentException 非法参数异常

  • IOException

IOException:操作输入流和输出流时可能出现的异常。

EOFException 文件已结束异常

FileNotFoundException 文件未找到异常

  • 其他

ClassCastException 类型转换异常类

ArrayStoreException 数组中包含不兼容的值抛出的异常

SQLException 操作数据库异常类

NoSuchFieldException 字段未找到异常

NoSuchMethodException 方法未找到抛出的异常

NumberFormatException 字符串转换为数字抛出的异常

StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常

IllegalAccessException 不允许访问某类异常

InstantiationException 当应用程序试图使用Class类中的newInstance()方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常


异常声明Throws

有些时候,我们是可以对异常进行处理的,但是又有些时候,我们根本就没有权限去处理某个异常。或者说,我处理不了,我就不处理了。
为了解决出错问题,Java针对这种情况,就提供了另一种处理方案:抛出。

public static void main(String[] args) {        method1();    }    private static void method1() {        try {            method2();        } catch (Exception e) {            System.out.println("捕获异常");        }    }    private static void method2() throws Exception {//抛出异常        int a = 3/0;    }

throw

throw:在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。如果出现了异常情况,我们可以把该异常抛出,这个时候的抛出的应该是异常的对象。

throws和throw的区别

  • throws

用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常

  • throw

用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定抛出了某种异常

public static void main(String[] args) {        method1();    }    private static void method1() {        try {            method2();        } catch (Exception e) {            System.out.println("捕获到异常,异常信息:" + e.getMessage());        }    }    private static void method2() throws Exception {        throw new Exception("手动抛出异常");    }

finally

  • 被finally控制的语句体一定会执行
  • 特殊情况:在执行到finally之前jvm退出了(比如System.exit(0))
final,finally和finalize的区别?
  • final
    最终的意思,可以修饰类,成员变量,成员方法
    修饰类,类不能被继承
    修饰变量,变量是常量
    修饰方法,方法不能被重写
  • finally
    是异常处理的一部分,用于释放资源。
    一般来说,代码肯定会执行,特殊情况:在执行到finally之前jvm退出了
  • finalize
    是Object类的一个方法,用于垃圾回收

自定义异常

使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。

在程序中使用自定义异常类,大体可分为以下几个步骤。

(1)创建自定义异常类。

(2)在方法中通过throw关键字抛出异常对象。

(3)如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。

(4)在出现异常方法的调用者中捕获并处理异常。


阅读全文
0 0
原创粉丝点击