异常
Java中异常类的体系结构
1.程序出现异常时正常现象【就跟人会生病一样】
2.Java中异常类Throwable【类】是顶级异常类
3.Throwable【类】有两个子类:
(1)Error【错误】
(2)Exception【异常】
Error与Exception的区别
Error是java程序运行中不可预料的异常情况,这种异常发生后,会直接导致JVM不可处理或者不可恢复的情况。所以这种异常不可能抓取到,比如OutOfMemoryError、NoClassDefFoundError等【癌症】
Exception是java程序运行中可预料的异常情况,咱们可以获取到这种异常,并且对这种异常进行业务外的处理【感冒】
运行时异常与非运行时异常的区别
- 非运行时异常—>检查性异常
必须在编写代码时,使用try catch捕获(比如:IOException异常) - 运行时异常—>非检查性异常
在代码编写时,可以忽略捕获操作(比如:ArrayIndexOutOfBoundsException),这种异常是在代码编写或者使用过程中通过规范可以避免发生的
Java 常见内置异常类
运行时异常—>非检查性异常
- ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数"除以零"时,抛出此类的一个实例。
- ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
- ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常。
- ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
- IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
- IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
- IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
- IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
- IndexOutOfBoundsException指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
- NegativeArraySizeException如果应用程序试图创建大小为负的数组,则抛出该异常。
- NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
- NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
- SecurityException 由安全管理器抛出的异常,指示存在安全侵犯。
- StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
- UnsupportedOperationException 当不支持请求的操作时,抛出该异常。
非运行时异常—>检查性异常
- ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
- CloneNotSupportedException 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
- IllegalAccessException 拒绝访问一个类的时候,抛出该异常。
- InstantiationException 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
- InterruptedException 一个线程被另一个线程中断,抛出该异常。
- NoSuchFieldException 请求的变量不存在
- NoSuchMethodException 请求的方法不存在
Java异常处理的原理
- 问题自己处理不了
如果出现异常,java会根据问题所描述的异常类,创建一个对象(实例)具体异常对象,然后将该对象抛给上一级【谁调用谁就是上一级】,throws 用来标明一个成员函数可能抛出的各种“异常”
具体步骤:
method具体出异常处 —> main主方法 —> jvm虚拟机 —> 将异常出现的位置和原因打印在控制台。 - 问题可以自己处理掉–通过try-catch代码块处理异常
将可能出现异常的java代码使用”try{异常可能发生的代码}catch(要抓捕的异常){异常处理方式}”块包裹,如果出现异常try{}就会捕获异常,终止代码的运行,将捕获的异常交给catch(){}去处理异常。
try{}catch(){}finally{}的用法
异常可以自己处理掉 — 通过try-catch代码块处理异常
格式:
try{
//异常可能发生的代码
}catch(//要抓捕的异常){
//异常处理方式
}finally{
//最终代码
}
(1)try —> 捕获可能发生的异常
(2)catch(//要抓捕的异常){//异常处理方式} —> 处理异常
catch后面的" ( ) "中专门定义具体异常类型
catch的 {} —> 具体异常的处理过程
(3)finally{} —> 有无异常都要执行的动作
例如:
public class TestMain {
public static void main(String[] args) {
//1.当我们无法判断try{}何种具体异常的时候,
//我们可以在catch块的参数中通过定义Exception/Throwable类的对象来代替具体异常类型。
/*
try {
int res=10/0;
System.out.println("res=="+res);
}catch(Exception e) {
System.out.println("处理异常!");
}
*/
//2.一个try{}后面可以跟随多个catch块,多个catch块需要按照具体异常的级别由低到高排列
try{
int numbers[]=new int[2];
numbers[0]=10;
numbers[1]=0;
int num1=numbers[0];
int num2=numbers[1];
int num3=num1/num2;
numbers[2]=num3;
System.out.println("程序执行完毕!!");
}catch(IndexOutOfBoundsException e3) {
System.out.println("处理数组下标越界异常!");
}catch(ArithmeticException e2) {
System.out.println("处理除数为0的异常!");
}catch(Exception e1) {
System.out.println("exception异常!");
}catch(Throwable e) {
System.out.println("Throwable异常!");
}finally {
System.out.println("有无异常都要执行");
}
}
}
1.当我们无法判断try{}何种具体异常的时候,我们可以在catch块的参数中通过定义Exception/Throwable类的对象来代替具体异常类型。
2.一个try{}后面可以跟随多个catch块,多个catch块需要按照具体异常的级别由低到高排列
3.finally{}–有无异常都要执行的动作
4.当try{}catch(){}finally{}出现在一个有返回值的方法中时,finally{}中的内容是在本方法的return语句之前运行。
例如:
public class Test08 {
public static void main(String[] args) {
int i=new Test08().test();
System.out.println(i);
}
public int test() {
int i=0;
try {
i=1;
return i;
} catch(Exception e){
i=2;
return i;
}
finally {
i=3;
System.out.println("i="+i);
}
}
}
Java异常处理注意事项
总结
- 捕获异常
多重捕获块
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型3 异常的变量名3){
// 程序代码
} - try catch注意事项:
①catch 不能独立于 try 存在。
②在 try/catch 后面添加 finally 块并非强制性要求的。
③try 代码后不能既没 catch 块也没 finally 块。
④try, catch, finally 块之间不能添加任何代码 - finally关键字
①finally 关键字用来创建在 try 代码块后面执行的代码块。
②无论是否发生异常,finally 代码块中的代码总会被执行。
③在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
④ finally 代码块出现在 catch 代码块最后
⑤当try{}catch(){}finally{}出现在一个有返回值的方法中时,finally{}中的内容是在本方法的return语句之前运行,最后返回的还是方法return
throws与throw关键字的用法
throws —> 声明方法抛出异常给上一级【谁调用谁就是上一级】
格式:访问限制修饰符 返回值类型 方法名称()throws 具体异常类型{ }
当我们无法判断读具体异常类型的时候使用Exception/Throwable代替
例如:
class DoClass {
public int testMethod() throws Exception{
int a=10/0;
return a;
}
}
public class TestMain {
public static void main(String[] args) throws Exception{
DoClass dc=new DoClass();
int res=dc.testMethod();
System.out.println("res=="+res);
}
}
throw —> 手动引发一个具体异常
自定义异常 —> 编写一个新类,继承Exception/Throwable,在构造方法中访问父类的构造方法。
class MyException extends Exception{
public MyException(String info) {
super(info);
}
}
class Person {
private int age;
public void setAge(int inputage) throws MyException{
if(inputage > 0 && inputage <= 200) {
age=inputage;
}else{
throw new MyException("你提供的年龄不符合要求!!");
}
}
public int getAge() {
return age;
}
}
public class TestMain {
public static void main(String[] args) throws MyException{
Person person=new Person();
person.setAge(-10);
System.out.println("age=="+person.getAge());
}
}
Java中常见运行时异常
- NullPointerException - 空指针引用异常
- ClassCastException - 类型强制转换异常。
- IllegalArgumentException - 传递非法参数异常。
- ArithmeticException - 算术运算异常
- ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
- IndexOutOfBoundsException - 下标越界异常
- NegativeArraySizeException - 创建一个大小为负数的数组错误异常
- NumberFormatException - 数字格式异常
- SecurityException - 安全异常
- UnsupportedOperationException - 不支持的操作异常
常见异常方法
异常方法
下面的列表是 Throwable 类的主要方法:
序号 方法及说明
1 public String getMessage()
返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
2 public Throwable getCause()
返回一个 Throwable 对象代表异常原因。
3 public String toString()
返回此 Throwable 的简短描述。
4 public void printStackTrace()
将此 Throwable 及其回溯打印到标准错误流。。
5 public StackTraceElement [] getStackTrace()
返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
6 public Throwable fillInStackTrace()
用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。