1)异常:
异常的基类是java.lang.Throwable,包含两个子类Exception和Error。系统内部错误不要抛出Error对象,尽量让程序结束;而异常是程序问题,可以捕获或处理。异常就是程序执行中的非正常事件,导致程序无法按预想的流程执行,Exceptions将错误信息传递给上层调用者,并报告异常语句信息。异常处理提供了除return之外的第二种退出途径,方法抛出异常对象信息,程序立即返回并拒绝返回任何值,此外与这个程序相关的语句将不再执行,而且若找不到异常处理程序,系统将完全退出。
对于throwable,常用的方法如下:
//返回异常发生时的详细信息
public string getMessage();
//返回异常发生时的简要描述
public string toString();
//返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以声称本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同
public string getLocalizedMessage();
//在控制台上打印Throwable对象封装的异常信息
public void printStackTrace();
在出现异常时我们应该不只打印异常信息,要做一些试图恢复的行为,如果用户可以通过其他方式恢复异常则采用已检查异常,如果无能为力则采用未检查异常。
2)Error分类:
用户输入错误、设备错误、物理限制等等。典型的有VirtualMachineError(堆栈、内存等错误)、LinkageError(A类依赖B类,但是在汇编后B不能转化成A)。
3)异常分类:
首先是运行时异常(runtimeException)包含类型转换、数组索引超界、访问空指针等等。非运行时异常包括文件读取超界、要打开不存在的文件、寻找不存在的类等。
4)检查异常:
编译器可以帮我们检查程序是否已经抛出或处理了可能的异常,我们要么捕获并处理异常,要么告诉编译器我们处理不了(不设置处理函数则编译器无法通过)。但是编译器是不检查error和运行时异常的,此时我们除了重写程序别无选择(未检查异常),因为编译没问题运行出问题。
Java的常见异常如下:
三、Java常见异常
第一类:RuntimeException子类:
序号 异常名称 异常描述
1 java.lang.ArrayIndexOutOfBoundsException 数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
2 java.lang.ArithmeticException 算术条件异常。譬如:整数除零等。
3 java.lang.SecurityException 安全性异常
4 java.lang.IllegalArgumentException 非法参数异常
5 java.lang.ArrayStoreException 数组中包含不兼容的值抛出的异常
6 java.lang.NegativeArraySizeException 数组长度为负异常
7 java.lang.NullPointerException 空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
第二类:IOException
序号 异常名称 异常描述
1 IOException 操作输入流和输出流时可能出现的异常
2 EOFException 文件已结束异常
3 FileNotFoundException 文件未找到异常
第三类:其他
序号 异常名称 异常描述
1 ClassCastException 类型转换异常类
2 ArrayStoreException 数组中包含不兼容的值抛出的异常
3 SQLException 操作数据库异常类
4 NoSuchFieldException 字段未找到异常
5 NoSuchMethodException 方法未找到抛出的异常
6 NumberFormatException 字符串转换为数字抛出的异常
7 StringIndexOutOfBoundsException 字符串索引超出范围抛出的异常
8 IllegalAccessException 不允许访问某类异常
9 InstantiationException
当应用程序试图使用Class类中的newInstance()方法创建
一个类的实例,而指定的类对象无法被实例化时,抛出该异常
10 java.lang.ClassNotFoundException 找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
5)未检查异常处理:
五个关键词try,catch,finally(前三个是真正意义上的捕获并处理),throws (本方法可能会存在XX异常),throw(始终抛出XX异常)。
注:未检查异常也可以用throws声明或try/ccatch进行捕获,但是不需要也不应该。
6)通过throws声明异常:
异常也应该是规约的一部分,我们应该在函数规约中添加@throws异常条件来对用户进行规约(未检查异常不得加入)。如果throws多个异常,可用逗号连接。每个函数的异常,来自它调用函数的异常以及自己定义的异常,我们需要告知用户需要处理这些异常。考虑子类型多态,如果子类型中override父类型中的函数,那么子类型中方法抛出的异常不能比父类抛出的更广泛,子类型方法可以抛出更具体或不抛出异常。一旦抛出异常,方法将不会再把控制权给调用它的用户,因此也无需考虑返回错误代码。
7)捕获异常:
异常发生后,如果找不到处理器就终止执行程序,在控制台打印出stack trace。否则,程序跳过try块,转而执行catch块。如果try块没有任何抛出异常的语句则程序跳过catch块;如果方法抛出了与catch中完全不一样的异常则程序立即exit。当然,异常也可以不再本方法中处理,而是推卸给调用方,但至少应二选一。
8)重抛异常:
catch语句也可以进行抛出异常,这样可以易辙异常类型,更方便客户端获取错误信息并处理,但这么做最好还是保留根原因。
9)finally块:
当异常抛出时,方法中正常执行的代码被终止,如果异常发生前曾经申请过某些资源,那么应该用finally对这些资源进行恰当的清理。不管是否遇到异常,finally中的内容都会被执行。