异常-day07

异常

今日学习内容:

  • 异常的体系
  • try-catch处理异常
  • finally语句块
  • throws关键字
  • throw关键字
  • 自定义异常

今日学习目标:

  • 掌握异常的继承体系(Throwable、Error、Exception的关系和区别)
  • 掌握异常的分类和区别(编译异常和运行异常)
  • 掌握try-catch捕获单个异常
  • 掌握try-catch-catch捕获多个异常
  • 掌握finally语句块执行特点
  • 掌握使用throws声明抛出自身不处理的异常,提醒调用者处理
  • 掌握使用throw在方法内部给调用者返回一个错误结果
  • 掌握自定义异常类

20. 异常概述

​ 异常就是程序在运行时出现的意外的,不正常的情况或结果。

​ 若异常产生后没有正确的处理,会导致程序的中断,以致造成损失。所以我们在开发中要尽量考虑到各种可能会发生的异常,并对其作出正确的处理,确保程序的正常执行。主流编程语言大多都提供了异常处理机制。

20.1. 异常的继承体系(掌握)

在这里插入图片描述

Throwable类有两个子类Error和Exception,分别表示错误和异常。

Exception 和Error的子类大都是以Error或Exception作为类名后缀。

20.2. Error(了解)

​ Error,表示代码运行时 JVM(Java 虚拟机)出现的问题。如系统崩溃或内存溢出等,不需要处理Error,

常见的Error。

  • StackOverflowError:当应用程序递归太深而发生堆栈溢出时,抛出该错误。比如死循环或者没有出口的递归调用。
  • OutOfMemoryError:因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象,这时抛出该错误。比如new了非常庞大数量的对象而没释放。
20.3. Exception(了解)

​ Exception,表示程序在运行时出现的一些不正常情况,一般大多数表示轻度到中度的问题,属于可预测、可恢复问题。如除数为0,数组索引越界等,这种情况下,程序员通过合理的异常处理,确保程序的正常运行直到结束,常见的Exception。

  • ArrayIndexOutOfBoundsException:用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。

  • ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。

  • NumberFormatException:数字格式化异常

  • NullPointerException:当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包括:

    调用 null 对象(空引用)的实例方法。

    访问或修改 null 对象的字段。

    将 null 作为一个数组,获得其长度等。

    String str = null;
    //非空判断
    if(str != null && str.trim().length() > 0){
    	str.length();
    }
    

21. 捕获异常

一旦出现异常,程序会立即终止,所以在开发中我们一定要处理异常,处理异常有两种方式:

一种是直接处理异常,一种是自身抛出异常,不处理。

21.1. 捕获单个异常(掌握)

处理异常代码格式:

try{
	//可能出现异常的代码
}catch(要捕获的异常类型 变量){
    //有要捕获的异常的时候执行这里的代码
	//处理捕获到的异常的代码
    //通过这个变量去访问异常对象中封装的数据
}

异常一旦产生,首先会实例化一个该类型异常对象,并把该对象赋值给对应的catch语句块里的异常类变量。

public class CatchDemo {
	public static void main(String[] args) {
		System.out.println("begin");
		//divide方法会出现错误,但是因为divide方法已经处理,不会影响到调用方法的继续向下执行。
		divide(17, 0);
		System.out.println("ending");//能够执行到ending
	}

	public static void divide(int a, int b) {
		try {
			System.out.println(a / b);
		} catch (ArithmeticException e) {  //捕获ArithmeticException类型的异常
			System.out.println("除法运算数有错误");
		}
	}
}

​ 当然也可以使用Exception接受所有的异常对象(多态)。开发中不建议捕获异常的时候使用Throwable,当然使用Throwable是没有一点问题的,只不过Throwable分为Error和Exception,而Error是没必要处理的,所以也没必要使用Throwable。

21.2. 访问异常信息(掌握)
常用方法方法说明
String getMessage()返回异常信息
void printStackTrace()打印异常类型名和异常信息,以及程序中出现异常的位置。

getMessage方法只获取异常的错误信息,一般获取之后,把错误信息给用户查看。

printStackTrace方法,用于打印异常具体信息,包含了异常信息,错误类型,错误位置,方便程序开发阶段的调试(一般要打开),也是JVM默认的异常处理机制。

public static void divide(int a, int b) {
	try {
		System.out.println(a / b);
	} catch (ArithmeticException e) {
		e.printStackTrace();
		System.out.println("异常信息:"+e.getMessage());
	}
}

目前就直接使用e.printStackTrace()就可以了。

21.3. 捕获多个异常(掌握)

处理多种类型异常代码格式:

try{
	//可能出现异常的代码
}catch(异常类型A 变量){
	//处理A类型异常的代码
}catch(异常类型B 变量){	
	//处理B类型异常的代码
}
...

若程序中还有未知的异常,我们可以在最后使用Exception进行统一捕获。

public class CatchDemo {
	public static void main(String[] args) {
		System.out.println("begin");
		divide("17", "0");
		System.out.println("ending");
	}

	public static void divide(String a, String b) {
		try {
			int x = Integer.parseInt(a);
			int y = Integer.parseInt(b);
			System.out.println(x / y);
		} catch (NumberFormatException e) {
			//处理数字格式化异常的代码
			e.printStackTrace();
		} catch (ArithmeticException e) {
			//处理算术异常的代码
			e.printStackTrace();
		} catch (Exception e) {
			//处理其他未知的异常
			e.printStackTrace();
		}
	}
}
21.4. finally语句块(掌握)

在处理多种异常类型时,必须先捕获子类型异常,后捕获父类型异常。

finally:表示最终的处理, 我们可以将代码最终必须执行的处理放在该代码块中

try-catch-finally格式

try{
	//可能抛出异常的代码
    
} catch(异常类型 变量){
	//处理异常代码
} finally{
	//无论有没有异常,最后都会执行的代码
}

try语句块必须和catch语句块或try和finally同在,不能单独存在try或catch或finally。

finally块总会执行,不论是否有错误出现。但如果try语句块中或catch语句块存在JVM退出代码(System.exit(0);),finally块就不会被执行了。

一般,我们把关闭资源的代码放在finally里面,保证资源总是能关闭。

22. 抛出异常

一旦出现异常,程序会立即终止,所以在开发中我们一定要处理异常,处理异常有两种方式:

一种是直接使用try-catch处理异常(已讲),一种是自身抛出异常,不处理,而抛出异常,有两种:

  • 方法里面会出现异常,但方法不想处理这个异常,使用throw抛出异常对象。
  • 方法里面可能会产生异常,自身不想处理,提醒调用该方法的方法做需要处理,使用throws关键字。
22.1. throws关键字(掌握)

在可能出现异常的方法上声明抛出可能会出现异常的类型,格式:

修饰符 返回值类型 方法名(参数列表..) throws 异常类A,异常类B...{
}

​ 抛出异常的原因:该方法自身处理不了该异常,只能使用throws提醒该方法的调用者需要处理异常。当然调用者也有两种处理方式: 自己捕获处理或再次抛出(要么try…catch ,要么也throws)。

public class ThrowsDemo {
	public static void main(String[] args) {
		try {
			divide(3, 1);
			divide(1, 0);//调用divide方法,调用者必须处理或再次抛出
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	//divide方法可能有异常,divide处理不了该异常,就抛出,让divide方法的调用者来处理
	public static void divide(int a, int b) throws Exception {
		System.out.println(a / b);
	}
}

若某方法内可能出现多个异常,那么也可以同时声明抛出对多个异常类型,异常类之间使用逗号隔开。

22.2. throw关键字(掌握)

当方法内,需要返回一个错误结果给调用者时,一般使用throw关键字在方法内手动抛出一个具体的异常对象。

public class ThrowDemo {
	public static void main(String[] args) {
		try {
			isExist("will");
		} catch (Exception e) {
			System.out.println(e.getMessage());//对不起,用户名will已经存在
		}
	}

	public static boolean isExist(String userName) throws Exception {
		String[] data = { "will", "lucy", "lily" }; 模拟已经注册的用户名
		if (userName != null && userName.length() > 0) {
			for (String name : data) {
				if (name.equals(userName)) { 用户名相同,证明该用户已经存在
					// 手动抛出一个错误表明提示代码的逻辑错误了
					throw new Exception("对不起,用户名" + userName + "已经存在");
				}
			}
		}
		return false;
	}
}

上述代码中throws和throw并不冲突,他们各自的作用是不一样的:

throw:当传入的参数已经存在,就返回一个错误结果给isExist方法的调用者。

throws:用于提醒isExist方法的调用者,需要处理异常。

throws和throw的区别

​ throws用于方法声明上,表示该方法不需要处理某种类型异常,也在提醒该方法调用者需要处理异常。

​ throw用于返回一个错误结果,抛出具体异常类的对象给调用者。

23. 异常分类

异常体系分成:checked(编译)异常和runtime(运行)和异常。

在这里插入图片描述

划分规则是,RuntimeException和其子类属于运行异常,异常除了运行异常,其他都是编译异常。

23.1. 运行异常(了解)

​ runtime异常,顾名思义在编译时期不被检测,只有在运行时期才会被检查出来。

​ 运行异常可以不使用try…catch处理,但一旦出现异常就将由JVM处理(打印堆栈信息)。RuntimeException(运行时异常)通常是指因设计或实现方式不当而导致的问题。程序员小心谨慎是可以避免的异常。如:事先判断对象是否为null就可以避免NullPointerException异常,事先检查除数不为0就可以避免ArithmeticException异常。

运行异常特点:

​ 在编译阶段,Java编译器检查不出来。一般的,程序可以不用使用try-catch和throws处理运行异常。

23.2. 编译异常(了解)

​ 编译被检查异常,顾名思义就是在编译时期就会被检测到的异常。除了RuntimeException以及子类以外,其他的Exception及其子类都是编译异常,有时候也称之为 非runtime异常。

特点:

​ 在编译阶段,Java编译器会检查出异常,也就说程序中一旦出现这类异常,要么使用try-catch语句捕获,要么使用throws语句声明抛出它,否则编译就不会通过。

简而言之:程序要求必须处理编译异常,使用try-catch或throws处理。

23.3. 自定义异常类(掌握)

一个异常类只表示某一种特定的异常类型,在项目开发中,可能会出现特定的逻辑错误,此时开发者可以对这些错误进行封装成异常。比如我们可以定义一个LogicException用于表示业务逻辑异常。

自定义异常的两种方式,可以继承Exception类或RuntimeException类。一般推荐继承RuntimeException类

继承异常类之后,一般的,需要提供无参构造方法和带一个String类型参数的构造器。

定义一个客户类,表示一个客户。

public class Customer {
	String name;

	public Customer(String name) {
		this.name = name;
	}
}

定义一个客户异常,专门表示抛出给用户看的异常类型。

public class CustomerException extends RuntimeException {
	//错误中可以添加自定义的属性,代表这个错误是针对哪个客户产生的。
	private Customer customer;

	public CustomerException(String message, Customer customer) {
		super(message);	//勿忘,表示把传递的异常信息存储到异常对象中
		this.customer = customer;
	}
}

测试类

public class ExceptionDemo {
	//定义一个方法,模拟在处理某个客户的时候出现了客户相关的逻辑错误
	public static boolean someCustomerLogic(String name) {
         //省略了若干业务代码
		throw new CustomerException("客户逻辑错误", new Customer(name));
	}

	public static void main(String[] args) {
		try {
			someCustomerLogic("will");
		} catch (Exception e) {
			//通过判断错误的类型,可以把错误强行转成CustomerException
			if (e instanceof CustomerException) {
				CustomerException ce = (CustomerException) e;
				System.out.println(ce.customer);//就可以得到错误中的客户对象了。
			}
		}
	}
}

学习优势:

1.包含java前后端从 0 ->1 全过程教学, 内容全面, 知识点不遗漏, 学完即可参加实际工作.
2.课程为目前项目开发常用的技术知识,向用人单位对标,学以致用。那些脱离实际,废弃不用的,太前沿的框架技术前期不建议学。
3.一起学习,打卡,一起交流,希望能营造一个和线下一样的学习环境。

需要进微信学习交流群, 或者想领取代码,文档,全套视频的同学请+v:lmm99964

在这里插入图片描述

在Python中,异常处理是非常重要的一部分。当程序运行时如果出现错误,如果没有异常处理,程序就会崩溃。为了避免这种情况,Python提供了异常处理机制。 在Python中,异常处理语句使用 `try` 和 `except` 关键字来实现。`try` 语句块中包含可能会发生异常的代码,如果这段代码出现了异常,则会跳转到 `except` 语句块中执行异常处理代码。 下面是一个简单的例子: ```python try: num = int(input("请输入一个整数:")) print(10/num) except ZeroDivisionError: print("除数不能为0") except ValueError: print("输入的不是整数") ``` 在上面的代码中,我们尝试将用户输入的字符串转换为整数,并将其用作除数计算 10/num。如果用户输入的是 0,则会触发 ZeroDivisionError 异常。如果用户输入的不是整数,则会触发 ValueError 异常。如果发生异常,则会跳转到对应的 except 语句块中执行处理代码。 除了可以指定具体的异常类型,也可以使用 `except Exception` 来捕获所有异常。例如: ```python try: num = int(input("请输入一个整数:")) print(10/num) except Exception as e: print("发生异常:", e) ``` 在上面的代码中,如果发生任何异常,都会跳转到 `except` 语句块中执行处理代码,并将异常信息打印出来。 除了 `try` 和 `except`,还有 `finally` 关键字,它指定的代码块无论是否发生异常都会执行。例如: ```python try: num = int(input("请输入一个整数:")) print(10/num) except Exception as e: print("发生异常:", e) finally: print("程序执行完毕") ``` 在上面的代码中,无论是否发生异常,都会执行 `finally` 中的代码,即输出“程序执行完毕”。 总之,在Python中,异常处理是非常重要的一部分,它可以有效避免程序崩溃,提高程序的健壮性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值