异常
Java标准库内建了一些通用的异常,这些类以Throwable为顶层父类。Throwable又派生出Error类和Exception类。
- 错误:Error类以及他的子类的实例,代表了JVM本身的错误。错误不能被程序员通过代码处理,Error很少出现。因此,程序员应该关注Exception为父类的分支下的各种异常类。
- 异常:Exception以及他的子类,代表程序运行时发送的各种不期望发生的事件。可以被Java异常处理机制使用,是异常处理的核心。
public class Test {
public static void main(String[] args) {
String[] src = new String[]{"a", "b", "c"};
for (int i = 0; i < 4; i++) {
//java.lang.ArrayIndexOutOfBoundsException数组越界
System.out.println(src[i]);
}
// A a = new A();
A a = null;
//java.lang.NullPointerException空指针
System.out.println(a.i);
}
}
class A {
int i;
}
Java异常层次结构图如下图所示
1)Error类
该类代表错误,指程序无法恢复的异常情况。对于所有错误类型以及其子类,都不要求程序进行处理。常见的Error类例如内存溢出StackOverflowError等。
2)Exception类
该类代表异常,指程序有可能恢复的异常情况。该类就是整个Java语言异常类体系中的父类。使用该类,可以代表所有异常的情况。 在Java API中,声明了几百个Exception的子类分别来代表各种各样的常见异常情况,这些类根据需要代表的情况位于不同的包中,这些类的类名均以 Exception作为类名的后缀。如果遇到的异常情况,Java API中没有对应的异常类进行代表,也可以声明新的异常类来代表特定的情况。在这些异常类中,根据是否是程序自身导致的异常,将所有的异常类分为两种:
a) RuntimeException及其所有子类
该类异常属于程序运行时异常,也就是由于程序自身的问题导致产生的异常,例如数组下标越界异常ArrayIndexOutOfBoundsException等。 该类异常在语法上不强制程序员必须处理,即使不处理这样的异常也不会出现语法错误。
b) 其它Exception子类
该类异常属于程序外部的问题引起的异常,也就是由于程序运行时某些外部问题导致产生的异常,例如文件不存在异常FileNotFoundException等。该类异常在语法上强制程序员必须进行处理,如果不进行处理则会出现语法错误。
常见的error类
异常类名 | 用途 |
---|---|
LinkageError | 动态链接失败 |
VirtualMachineError | 虚拟机错误 |
AWTError | AWT错误 |
常见运行时异常类
异常类名 | 用途 |
---|---|
ArithmeticException | 数学运算异常,比如除数为零的异常 |
IndexOutOfBoundsException | 下标越界异常,比如集合、数组等 |
ArrayIndexOutOfBoundsException | 访问数组元素的下标越界异常 |
StringIndexOutOfBoundsException | 字符串下标越界异常 |
ClassCaseException | 类强制转换异常 |
NullpointerException | 当程序试图访问一个空数组中的元素,或访问一个空对象中的方法或变量时产生的异常。 |
常用的非运行时异常
异常类名 | 用途 |
---|---|
ClassNotFoundException | 指定类或接口不存在的异常 |
IllegalAccessException | 非法访问异常 |
Ioexception | 输入输出异常 |
FileNotFoundException | 找不到指定文件的异常 |
ProtocolException | 网络协议异常 |
SocketException | Socket操作异常 |
MalformedURLException | 统一资源定位符(URL)的格式不正确的异常 |
异常处理机制
捕获异常
A a = null;
// try catch是为了防止程序可能出现的异常,在捕获异常的代码块中,如果前面的代码有异常了,就不会执行后面的
try { //用try{}来括住一段可能出现异常的代码段
System.out.println(a.i); //由于异常,使中断,可以通过异常处理机制防止程序的中断
} catch (Exception e) { //当不知道捕获的异常类型时,可以直接使用所有异常的父类Exception
System.out.println(e.getMessage());
e.printStackTrace();
} finally { //这个finally可以写也可以不写,它是捕获异常的体系中,最终一定会执行的部分,未来学习IO操作和JDBC会接触
System.out.println("会执行");
}
System.out.println("OK");
- getMessage()方法:用来得到有关异常事件的信息
- printStackTrace()方法:用来跟踪异常事件发生时执行堆栈的内容
抛出异常
public class Test1 {
public static void main(String[] args) {
B b = new B();
try {
b.test();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class B {
int a;
public void test() throws Exception { //可以使用throws在代码这抛出异常,在调用方法中去捕获处理
B b = null;
System.out.println(b.a);
}
}
注意:重写方法不能抛出比被重写方法范围更大的异常
人工抛出异常
throw new Exception("xxxxxx");
用户自定义异常类:一般很少用到