10. 异常

10.1 异常情况

角标越界异常 ArrayIndexOutOfBoundsException

int[] a = new int[3];
System.out.println((a[3]));;//throw new ArrayIndexOutOfBoundsException(index);
System.out.printl("over");//前一句出现异常,程序中断,此句不执行
  1. 没有找到角标3,运行时发生了异常。java将出现异常的信息直接封装到对象中
  2. 系统自动抛出对应的异常 new ArrayIndexOutOfBoundsException(index)
  3. JVM进行最终处理,将问题的名称,信息,位置都显示屏幕上

运行结果
在这里插入图片描述
Exception in thread “main” 异常发生在名字为main的线程中 main主线程(主函数所在的线程)
java.lang.ArrayIndexOutOfBoundsException: 3 异常名称 异常原因
at Part1.test.practice.main(practice.java:8) 异常的位置(异常发生的位置)
at Part1.test.practice.main(practice.java:8) 异常的位置(调用异常发生的位置)

10.2 try…catch捕获异常

抛出异常

执行try块内代码时出现异常,系统自动生成一个异常对象,提交给Java运行时的环境

捕获异常

Java运行时的环境接收到异常对象时,开始寻找处理该异常对象的catch块,进行处理
若找不到异常对象的catch块,运行终止,程序退出

try{
	//业务实现代码
	.....
}catch(Exception e){//参数为一个异常类对象e
	//处理异常
	.......
}

每一个catch块专门用于处理该异常类及其子类的异常实例

10.3 异常类

  • Throwable为所有异常类的父类

在这里插入图片描述

Checked异常和Runtime异常体系

Checked异常(只有JAVA提供,必须显式处理)

处理方式:
1. try…catch处理(当前方法明确知道错误)
2. 定义方法时抛出异常(当前方法不知道怎样处理)

Runtime异常所有RuntimeException异常类及其子类
无需显式声明抛出

  • RuntimeException的常见异常子类
  1. ArithmeticException 数学异常 (5/0)
  2. FileNotFoundException 文件未找到异常
  3. NullPointerException 空指针异常(引用变量为null)
  4. IndexOutOfBoundsException 下标越界异常
  5. ClassCastException 类型转换异常
  6. NumberFormatException 字符串转换为数字异常
try{
	.....
}catch(ArrayIndexOutOfBoundsException e1){
	.....
}catch(RuntimeException e2){
	......
}catch(Exception e3){
	......
}

注意

捕获异常时,所有父类异常的catch块要放在子类异常catch块的后面
保障子类异常catch块有执行的机会

10.4 多异常捕获

  • 多种异常类型之间用 | 分隔开
  • 捕获多种异常类型时,异常变量默认用final修饰,不可重新赋值 2
  • 捕获一种异常类型时,异常变量可重新赋值 3
try {
	.........
}catch(IndexOutOfBoundsException | NumberFormatException e){
	System.out.println("发生越界异常或数字格式异常!");
	//e = new IndexOutOfBoundsException("test");   2
}catch(Exception e){
	System.out.println("发生其他异常!");
	e = new RuntimeException("test");        //3
}

10.5 访问异常信息

通过catch块后的异常形参e来访问异常对象信息

  • getMessage() 返回异常的描述字符串
  • printStackTrace() 输出异常的跟踪栈信息
  • getStackTrace() 返回异常的跟踪栈信息
  • printStackTrace(PrintStream s) 将异常的跟踪栈信息输出到指定输出流

10.6 finally

程序在try块中打开了一些物理资源,必须显示回收。因为异常会引发程序跳转,导致不能及时回收,而finally代码块中存放的代码总是被执行

  • 异常处理语法结构中,只有try块是必需的
  • finally块必须在所有catch块后
  • 执行finally块内容不收return影响
  • 异常处理的finally块总会被执行,除非使用==System.exit(1)==退出虚拟机
try {
	int[] a = new int[3];
	System.out.println(a[5]);
}catch(IndexOutOfBoundsException e){
	e.printStackTrace();
	System.out.println();
	return;
	//System.exit(1)退出虚拟机,则不会再执行finally块
}catch(Exception e){
	System.out.println("发生其他异常!");
}finally {
	System.out.println("一定被执行");//此语句不受return影响
}
  • 尽量不要再finally块中使用return,throw终止方法的语句(可能导致try块,catch块中的return,throw失效等

finally块try块都包含终止语句时的执行步骤:

  1. 执行try块||catch块遇到return||throw
  2. 终止语句(不结束方法)寻找异常流程中的finally块
  3. 若找见finally块,执行包含代码
  4. 跳出finally块,继续执行try块||catch块中的return||throw

10.7 throws声明抛出异常

当前方法不知如何处理异常,该异常应由上一级调用者处理。
若main函数也不知如何处理异常,也可以throws声明抛出异常交由JVM处理
JVM打印异常的跟踪栈信息,终止程序执行

	public static void main(String[] args)
	 throws IndexOutOfBoundsException{//声明越界异常
			int[] a = new int[3];
			System.out.println(a[5]);
	}	

声明多个异常之间用,隔开

throws IndexOutOfBoundsException,NullPointerException 

子类声明抛出的异常类型只能是父类的子类或相同

10.8 throw抛出异常

throw抛出的是一个异常实例,每次只能抛出一个

public class throw{
	public static void main(String[] args) {
		try {
		//调用抛出Checked类型的异常
		//必须显式捕获  或  在main方法中再次抛出
			throwChecked(-3);
		}catch(Exception e){
			System.out.println(e.getMessage());
		}
		//调用抛出Runtime类型的异常
		//既可显式捕获,也可不做理会,交由调用者处理
		throwRuntime(3);
	}
	
	public static void throwChecked(int a)throws Exception{
		if(a > 0) {
			throw new Exception("a的值大于0,不符合要求");
		}
	}
	
	public static void throwRuntime(int a){
		if(a > 0) {
			throw new RuntimeException("a的值大于0,不符合要求");
		}
	}
}

10.9 自定义异常

//自定义异常继承自基类  Exception 或  RuntimeException
public class except extends Exception{
	//无参构造函数
	public practice() {
		
	}
	//通过super调用父类构造器,字符串S作为异常描述信息
	public practice(String s) {
		super(s);
	}
}

上课异常类

public class test {
	public static void main(String[] args) {
		Teacher t=new Teacher("赵老师");
		try {
		//上课函数可能有异常
		t.teach();
		//若捕获到不能上课的异常,打印异常信息,下课,放学
		} catch (ClassNotContinueException e) {
		e.printStackTrace();
		System.out.println("下课  放学!");
		}
	}
}
	/*
	老师用电脑上课
	电脑会有以下几个问题
		1.蓝屏    -->>重启-->>上课
		2.冒烟    -->>无法上课
	*/
//老师类
class Teacher{
	String name;
	Computer com;
	public Teacher(String name) {
   		this.name=name;
		this.com=new Computer(2);//定义电脑冒烟
	}
	//上课函数声明抛出不能继续上课的异常
	public void teach() throws ClassNotContinueException {
		try {
			//电脑状态可能异常
			com.start();
		//捕获到蓝屏异常
		} catch (BlueScreenException e) {
			e.printStackTrace();
			//重启
			com.restart();
		//捕获到冒烟异常
		} catch (MaoYanException e) {
			e.printStackTrace();
			//异常的转换,抛出不能上课的异常
			throw new ClassNotContinueException("课上不成了!");
		}
		//电脑正常,开始上课
		System.out.println(this.name+"开始上课......");
		}
}
//电脑类
class Computer{
	int status=0;//0 正常 1 蓝屏 2冒烟
	public Computer(int status) {
		this.status=status;
	}
	//重启函数
	public void restart() {
		status=0;
		System.out.println("电脑重启......");
	}
	//电脑状态声明抛出蓝屏,冒烟异常
	public void start() throws BlueScreenException, MaoYanException{
		System.out.println("电脑开机......");
		if(status==1){
			throw new BlueScreenException("电脑蓝屏了......");
		}
		if(status==2){
			throw new MaoYanException("电脑主板烧了,电脑冒烟了......");
		}
	}
}
//蓝屏异常类
class BlueScreenException extends Exception{
	public BlueScreenException(String msg) {
		super(msg);
	}
}
//冒烟异常类
class MaoYanException extends Exception{
	public MaoYanException(String msg) {
		super(msg);
	}
}
//不能上课异常类
class ClassNotContinueException extends Exception{
	public ClassNotContinueException(String msg) {
		super(msg);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43498251/article/details/88557907
10.