Java中的异常
总结了一下异常的种类,和解决方式
一、概念
-
异常的概念:程序运行的过程中出现的非正常的情况,会导致程序的终止
-
处理异常的意义:
当出现异常的时候,执行准备好的代码,以减少损失
-
异常的分类:
|--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<TestOOM> 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); } }
-