Exception:程序中不正常的行为被称为异常或者错误
异常的体系结构:
Throwable
Error:程序员不能处理的情况,需要修改底层的源代码
Exception:需要由程序员来进行处理的
RuntimeException:在运行阶段出现的问题
编译异常:在编译阶段就出现的问题
处理异常的两种方式:
自己解决:try...catch...finally
让别人解决:throws
创建异常对象
new 异常类("错误信息")
抛出异常对象 throw new 异常类("错误信息")
注意事项:
1、运行时异常可以抛出,不进行处理,让虚拟机处理
2、如果父类抛出了异常子类覆盖父类的时候
(1)不抛出任何异常
(2)抛出和父类的方法一样的异常
(3)抛出和父类方法一样的异常的子异常
3、一个try可以匹配多个catch,如果catch的异常类之间存在继承关系,子类异常必须写在
父类异常前面
A.java -----> 编译器进行编译javac.exe -------> A.class ----------> 解释器运行java.exe
如果程序有问题就会出现编译异常
------> 字节码(机器码)
异常和错误的区别
异常:指在程序编译、运行期间发生了某种特殊情况(XXXXXException),我们可以对异常进行具体的处理
如果不进行处理,程序就会结束运行
System.out.println(10/0);
错误:指程序在运行期间发生了某些错误(XXXXError),Error错误通常没有具体的处理方式,并且程序会结束
运行,Error错误发生的往往是系统级别的问题,jvm所在的系统发生问题并且反馈给JVM,我们无法处理
只能修改代码
int[] arr = new int[102410241024];
throw关键字
抛出异常对象
作用:可以使用throw关键字,在指定的方法中抛出指定的异常对象
格式:throw new XXXXXException("填写异常产生的原因")
注意:
1、throw关键字必须写在方法的内部
2、throw关键字后面new的对象必须时Exception 或者 Exception的子类
3、throw关键字
情况1:抛出的是检查异常,我们必须处理这个异常
throw new Exception("异常原因");
//我们必须手动处理这个异常
//处理异常的方式有两种 throws try...catch....
情况2:抛出的是运行时异常(RuntimeException 或者 RuntimeException的子类)
我们可以不进行处理,由jvm进行处理
try...catch...finally 捕获异常(自己处理)
java中对异常有针对性的语句进行捕获,可以对出现异常运行指定的方式的处理
格式:
try{
//可能出现异常的代码(没有异常的代码也可以定义在try语句块中)
//try语句块中,一旦出现了异常,则抛出异常的那个语句后面的代码就不执行了
//疑似病例(可能得病了,也可能没有)
}catch(异常类名 变量名){//数据类型 必须时异常类或者异常的子类
//新冠确诊 匹配这个,才会执行代码,就会打印信息
//就会进入隔离区
//异常的处理语句,抓取到和异常类名一样的对象才会执行
}catch(异常类名 变量名){
//普通流感 匹配这个,才会执行代码,就会打印信息
}finally{
//不论是否有异常发生,finally里面的内容个都会执行(执行一遍)
}
System.out.println("1***");//一下的代码就可以正常执行了
注意:
1、try 存放的是可能出现异常的代码,异常有0个或者n个
2、catch用来进行某种异常的抓去,实现对抓到的异常对象进行处理
一个try可以匹配多个catch,catch是有顺序要求
(1)如果多个catch的异常类之间没有继承关系,顺序可以随便写
(2)如果多个catch之间存在继承关系,则子类异常必须放在父类异常的上面
3、finally:不论是否有异常都会执行一
public static void main(String[] args) {
try {
int a = 10 / 0;
}catch (ArithmeticException a){
System.out.println("算术异常,除数不能为0");
}catch (RuntimeException r){
System.out.println("出现运行时异常");
}catch (Exception e){
System.out.println("出现异常");
}finally {
for(int i = 0; i < 10; i++){
System.out.println(i);
}
}
for(int i = 0; i < 10; i++){
System.out.println("----------" + i);
}
System.out.println("程序执行完了");
}
组合方式:
1、try...catch...
2、try...catch...finally
3、try...catch...catch...finally
4、try...finally
throws抛出异常(交给别人处理)
作用:
当方法内部抛出异常对象的时候,我们必须处理这个异常对象
如果使用throws的话就就将异常抛出了
抛给谁?抛给方法的调用者进行处理
如果到了主方法,还继续往外抛,则最终交给jvm(1、打印错误信息 2、中断程序的执行)
格式:
public 返回值类型 方法名(参数列表)throws AaaaaaException,BbbbbException{
throw new AaaaaaException("产生的原因");
throw new BbbbbException("产生的原因");
}
注意:
throws关键字必须写在方法的声明出
throws关键字后面必须时异常或者异常的子类
方法内部如果抛出了多个异常对象,那么throws后面必须声明多个异常对象
如果抛出多个异常对象存在子父类关系,就执行抛出父类异常
throw和throws的区别
java中的异常抛出
throw: 将要产生的异常(动作)
throws:声明一个将要抛出何种类型的异常(声明)
throw 定义在方法的内部,后面跟的是异常对象
new 异常类的构造器(参数值);
同时只能抛出一个异常对象,抛出的异常对象后面的代码就不执行了
throw new XXXException("异常的原因")
throws 定义在方法的声明上,后面跟的是异常的类型
后面可以跟多个异常类型
public static 返回值数据类型 方法名(参数列表)
throws XXXException,XXXException{
}
异常在重写中的细节
1、子类重写父类中的方法的时候,如果父类方法声明了异常,子类重写的方法
可以声明和父类方法相同的异常或者声明父类异常的子类异常
2、父类的方法没有抛出异常的时候子类重写的方法可以抛出异常,但是一般也不抛出
如果子类产生了检查异常,则自己在方法的内部使用try...catch...进行处理
不要抛出
如果子产生了运行时异常,则不用不用自己处理,因为jvm会进行处理
自定义异常
1、创建类继承于Exception或者继承于它的子类
2、在类中定义两个构造器,一个是没有参数的,一个是有String类型参数的
3、分别在构造方法中调用对应的父类的构造方法
如何使用自己定义的异常
如果程序没有满足你的需求的时候,可以抛出一个自定义的异常对象
throw new 自定义异常("原因")
自定义一个异常 要求如果用户的年龄大于200 或者小于 0 抛出异常
public class People {
private String name;
private int age;
public People() {
}
public People(String name, int age) throws NoAgeException{
if(age > 200 || age < 0){
throw new NoAgeException("年龄是一个非法的值");
}
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public class PeopleTest {
public static void main(String[] args) {
People people = null;
try {
people = new People("天山童姥",18);
System.out.println(people.toString());
} catch (NoAgeException e) {
e.printStackTrace();
}
}
}