JAVA学习记录6——异常
一、异常的概念
Java中程序执行发生的不正常情况称为异常(开发过程中的语法错误和逻辑错误不是异常)
执行过程中发生的异常事件可分为两类:
- Error(错误):Java虚拟机无法解决的严重问题。程序会崩溃。如:JVM系统内部出错、资源耗尽等严重情况。StackOverflowError(栈溢出)OOM(out of memory内存不足)
- Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对的代码进行处理。如:空指针异常NullPointer,试图读取不存在的文件,网络连接中断等。
Exception可分为两大类:运行时异常和编译时异常
如ArithmeticException算数异常,属于运行异常
二、异常体系图
异常根类Throwable,继承了Object,实现了Serializable接口。Exception中RuntimeException类和其子类均为运行异常,其它编译异常与RuntimeException平级
-
运行时异常编译器检查不出,一般是编程时的逻辑错误,运行时异常可不作处理(会默认使用throws处理),因为很普遍,若全处理可能会对程序的可读性和运行效率产生影响
-
编译时异常编译器要求必须处理
三、常见的异常
常见运行时异常:
1.NullPointerException空指针异常
当应用程序试图在需要对象的地方使用null时(对象未创建就使用),抛出该异常
eg:
String name = null;
System.out.println(name.length());
2.ArithmeticException数学运算异常
当出现异常的运算条件时,抛出该异常
3.ArrayIndexOutOfBoundsException数组下标越界异常
用非法索引访问数组时抛出的异常。如果索引为负或>=数组大小,则为非法索引
4.ClassCastException类型转换异常
当试图将对象强制转换为不是实例的子类时,抛出该异常
eg:
public class Test {
public static void main(String[] args) {
A b = new B();//向上转型
B b2 = (B)b;//向下转型
C c = (C)b;//异常,B、C无继承关系
}
}
class A {}
class B extends A {}
class C extends A {}
5.NumberFormatException数字格式不正确异常
当应用程序试图将字符串转成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。用这种异常可以确保输入的是满足条件的数字
eg:
String name = "字符串";
int num = Integer.parseInt(name);//string转成int,异常
常见的编译异常
主要在网络、数据库、文件操作
-
SQLException
操作数据库时,查询表可能发生异常 -
IOException
操作文件时发生的异常 -
FileNotFoundException
操作一个不存在的文件时发生异常 -
ClassNotFoundException
加载类,而类不存在时的异常 -
EOFException
操作文件,到文件末尾时的异常 -
IllegalArguementException
参数异常
四、异常处理
Java提供了异常处理机制try-catch-finally(在代码中捕获发生的异常,自行处理)和throws(将发生的异常抛出,交给调用者(方法)来处理,最顶级处理者就是JVM)解决异常导致整个系统崩溃的问题。进行异常处理,则即使出现异常,程序仍可继续运行
1)try-catch-finally
选中一段代码块,用快捷键ctrl + alt + T打开环绕方式,可选择try-catch。
可以try-catch(没有必须执行的逻辑),也可try-finally(没有捕获异常,必须执行finally中逻辑)
当异常发生时,try内的代码停止执行,系统将异常封装成Exception对象e,传递给catch,catch中可捕获异常,可自行写逻辑处理,如果没有发生异常,catch不执行。finally中是始终都执行的语句,可以控制资源关闭
如果在try中有return语句,finally始终会在return之前执行
可以有多个catch语句,设置e的异常类型,捕获不同异常,要求父类异常在后,子类异常在前,发生异常只匹配一个catch
try {
int res = 10/0;
} catch (Exception e) {
e.printStackTrace();
//此处可捕获异常,输出异常信息e.getMessage
//可自行写逻辑处理
//System.out.println(e.getMessage());
} finally {
//不管try中是否有异常发生,始终都执行
}
2)throws
处理机制:
将发生的异常抛出,交给调用者(方法)来处理,最顶级处理者就是JVM,JVM可处理异常,输出异常信息,退出程序。若出现异常没有写相应的处理机制,则默认会有throws,将异常抛至JVM处理
throws可声明抛出异常的列表,throws后的异常类型可以是方法中产生的异常类型,也可是它的父类。也可是多个异常组成的列表
public void f1() throws Exception {
}
可选择将异常抛给上一级,或应用try-catch-finally(二选一)
子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么是父类抛出异常类型的子类型
//要在f1也抛出相应的编译异常,或对f3用try-catch
public static void f1() {
f3(); //直接调用会报错
}
public static void f3() throws FileNotFoundException{
//在此处操作不存在的文件,抛出编译异常
FileInputSream fis = new FileInputStream("d://a.txt");
}
如果f3中抛出运行异常,则不用处理
五、自定义异常
当程序中出现了某些错误,但该错误信息没有在Throwable子类中描述处理,则可以自己设计异常类,用于描述该错误信息
定义类:自定义类名,继承Exception或RuntimeException(一般继承运行异常,好处是可以使用默认的处理机制)
//自定义异常
class XException extends RunTimeException {
public XException(String message) {//构造器
super(message);
}
}
//在异常代码处调用
throw new XException("自定义错误信息");
throws 与 throw 的对比: