异常
一、概念
异常的概念:程序运行的过程中出现的非正常的情况,会导致程序的终止
处理异常的意义:
当出现异常的时候,执行准备好的代码,以减少损失
异常的分类:
|--Throwable
|--Error
|--Exception
|--RuntimeException
|--非RuntimeException
二、Throwable类
Throwable是所有Java异常和错误类的父类,位于java.lang包中
常用方法:
String getMessage():获取字符串类型异常信息
void printStackTrace():打印异常或错误的栈追踪信息
三、Error类
Error是Throwable的子类
Error通常是严重的错误,无法通过代码直接解决
常见的Error
java.lang.StackOverflowError:栈溢出错误
package com.baizhi.testException;
public class TestError {
static int count = 1;
public static void main(String[] args) {
method();
}
public static void method() {
System.out.println(count++);
//递归调用自身
method();
}
}
java.lang.OutOfMemoryError:内存溢出错误
package com.baizhi.testException;
import java.util.ArrayList;
import java.util.List;
public class TestOutOfMemoryError {
public static void main(String[] args) {
List list = new ArrayList<>();
while(true) {
//不断的创建对象,并且存入集合
list.add(new TestOOM());
}
}
}
class TestOOM{
static int count = 1;
public TestOOM() {
System.out.println(count++);
}
}
四、Exception类
Exception是Throwable的子类
Exception通常是程序运行过程中遇到的问题,会导致程序停止运行
通常将Exception分为RuntimeException(运行时异常/未检查异常)和非RuntimeException(编译时异常/已检查异常)
异常是以对象的方式产生与传递的,所以异常可以使用new语句产生
异常的传递:程序遇到异常,沿方法调用向回传递直至虚拟机,程序终止
五、运行时异常/未检查异常(RuntimeException)
分类方式:RuntimeException自身或者其子类
特点:编译器不会对其做出反应,在运行时可能出错,可处理也可不处理
常见的运行时异常:
java.lang.ArrayIndexOutOfBoundsException:下标越界
java.lang.NullPointerException:空指针异常
java.lang.ClassCastException:类型转换异常
java.lang.NumberFormatException:数字格式转换异常
处理方式:代码严谨
六、编译时异常/已检查异常(非RuntimeException)
分类方式:除RuntimeException之外的所有异常
特点:编译器会对其进行检查,必须做出处理
异常的处理:
声明抛出(消极处理方式):
在方法的实现体中使用throw关键字声明抛出单个异常对象
public void method() {
throw new RuntimeException();
}
在方法的声明部分使用throws关键字声明抛出多个异常类型
public void method() throws IOException,
ClassNotFoundException,NullPointerException{
}
throw和throws的区别:
throw用于方法的实现位置,只能声明抛出单个的异常对象
throws用于方法的声明位置,可以抛出多个异常的类型
使用try...catch处理(积极处理方式):
package com.baizhi.test;
import java.io.FileNotFoundException;
import java.io.IOException;
public class TestException {
public static void main(String[] args) {
try {
//调用的方法声明抛出了异常
method();
//对异常对象进行处理
}catch(FileNotFoundException e1) {
//父类类型异常必须声明在靠后的位置
}catch (IOException e2) {
//异常的处理可以使用多态
}catch (Exception e3) {
}
}
public static void method() throws IOException {
}
}
finally的使用:finally中的代码最终一定会被执行,通常用于资源的释放
package com.baizhi.test;
import java.io.IOException;
public class TestException {
public static void main(String[] args) {
try {
//调用的方法声明抛出了异常
method();
//对异常对象进行处理
}catch (Exception e) {
}finally {
//资源释放
}
}
public static void method() throws IOException {
}
}
其他形式
//基本形式
try{}catch(){}
//多个catch
try{}catch(){}catch(){}
//finally
try{}catch(){}finally{}
try{}catch(){}catch(){}finally{}
//不需要catch
try{}finally{}
//嵌套
try{
try{}catch(){}finally{}
}catch(){
try{}catch(){}finally{}
}finally{
try{}catch(){}finally{}
}
异常类的常用方法:
printStackTrace():打印异常的栈追踪信息
getMessage():获取异常类型信息
方法的覆盖对于异常的要求
子类中不能抛出较父类更多类型或者更宽类型的异常
方法的覆盖最终版本:
在继承关系中
方法名,形参列表,返回值类型都相同
访问修饰符较父类相同或更宽
子类中不能抛出较父类更多类型或者更宽类型的异常
七、自定义异常
原则:
如果需要自定义编译时异常,则继承Exception类
如果需要自定义运行时异常,则继承RuntimeException类
分别提供有参数和无参数构造方法
//自定义编译时异常,需要继承Exception
class MyException extends Exception{
//提供无参数构造方法
public MyException() {
super();
}
//提供有参数构造方法,以便于打印异常信息
public MyException(String message) {
super(message);
}
}
//自定义运行时异常,需要继承RuntimeException
class MyRuntimeException extends RuntimeException{
//提供无参数构造方法
public MyRuntimeException() {
super();
}
//提供有参数构造方法,以便于打印异常信息
public MyRuntimeException(String message) {
super(message);
}
}