Java异常机制

一.异常的分类

一.异常类的继承图
在这里插入图片描述
1.所有的异常对象都是派生于Throwable类
2.error类表示java内部错误,出现这样的问题一般不需要我们解决,也没法解决。
3.Exception类及其子类,Exception主要有两个子类,IOException和RuntimeException。
IOException是IO错误导致的。RuntimeException类异常表示运行时异常,可以加以避免。

二.检查类异常(checked)和非检查类异常(unchecked)
检查类异常(checked)就是指在编译过程中,编译器就会报错,程序员必须去解决
非检查类异常(unchecked)是指运行时候才会报错的异常
其中:error类和RuntimeException类属于非检查异常类(unchecked)
而IOException属于检查类异常。

二.运行时异常和解决方法

运行时异常为非检查类异常,编译过程中不会报错,但运行时会报错,一般可以使用逻辑代码来解决这样的异常。总之 运行时异常是需要程序员去检查和处理的。
例如
1.除以0异常
在这里插入图片描述
2.类强制转换异常
在这里插入图片描述
在这里插入图片描述
3.空指针异常
加粗样式
4.数组越界异常在这里插入图片描述
5.数字格式化异常
在这里插入图片描述

三.异常的处理过程

下面先来看一段例子
在这里插入图片描述
此处的异常应该属于RuntimeException,是unchecked异常(除以0异常)。
这段程序中异常处理的过程应该是这样的:main方法中调用run()方法;于是进入run()方法内部,执行int a = 10/0;产生异常,但是在本方法中未找到处理,于是返回调用处,也就是main方法,但是main方法中依然没有处理方法,于是只能默认打印异常信息。

四.异常处理1:捕获try_catch_finally

捕获异常,我们使用try catch 关键字,
try中代码表示可能出现异常的代码块,
catch中的代码块表示捕捉到该异常之后需要进行的操作。
finally表示无论有无异常,都会执行的内容。
在这里插入图片描述
此时,当我们使用Java代码想要读取一个文件中的字符时,这里就发生了check异常,这是因为我们调用了FileReader这个类,这个类在源代码中本身就是抛出异常的,抛出异常后,本身不做处理,交给调用者取处理,这里调用者就是我们的readFile()方法。
在这里插入图片描述
我们可以使用try catch捕获异常 或者继续throws 抛出 ,这里我们使用try catch语句。
在这里插入图片描述
在try catch语句中可以有多个catch来处理不同的异常,但是顺序要从上到下,由子类到父类的顺序来编写,(子类异常在前,父类异常在后)

显然在本案例中,try语句块的第一句出现了文件没有找到异常,之后从上到下寻找对应的catch,当执行完第一个对应的catch语句后,之后的catch就不在在被执行,直接到finally语句块。不仅如此,当try语句块中发现异常之后,try语句块之后的代码也不会再执行。
在这里插入图片描述
当第一句话发生异常的时候,temp1已经之后的try语句就都没有在执行。对应的执行了相应的catch语句块,temp3并没有被执行。最后执行到finally的关闭指令。

五.抛出异常 throws

try catch语句可以用来处理方法中的异常,但是我们也可以暂时不处理可能会发生的异常
,选择是向上抛出异常(向调用出抛出,让调用者处理),而本身不做处理。
在这里插入图片描述
在run方法中,将可能会发生的数组溢出的异常直接抛出,交给调用者取处理,就是我们的main方法,main方法中可以继续抛出异常,将异常抛给JRE,然后JRE默认打印异常信息,也可以我们自己来处理异常 用trycatch
在这里插入图片描述

六.手动抛出异常 throw

在这里插入图片描述
程序执行到throw语句的时候立即停止,后面的语句都不会执行。

七.自定义异常

自定义类只需要从Exception类和他的子类中或者它的子类派生一个类
自定义异常类如果继承Exception类,则为受检查异常,必须对其进行异常处理;
如果不想处理,可以让自定义异常类继承运行时异常RuntimeException

习惯上 ,自定义异常类应该包含2个构造器:一个是默认的构造器。另一个是带有详细信息的构造器

实例1 继承Exception类 ,其类型为check异常,也就是手动抛出这个类后,必须进行抛出或者trycatch处理

public class define2 {
	public static void main(String[] args) {
		Student s = new Student();
		s.setAge(140);
		System.out.println(s.getAge());
	}
}

class Student{
	private int age;
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		if(age<=0||age>=130) {
			try {								//必须进行处理
				throw new illegalAge("年龄输入错误");
			} catch (illegalAge e) {
				e.printStackTrace();
			}
		}
			this.age = age;
	}

}

class illegalAge extends Exception{
	public illegalAge() {		//一个是默认的构造器
	
	}
	public illegalAge(String sth) { //另一个是带有详细信息的构造器
		super(sth);
	}
}

实例2 继承RunTimeException类 ,其类型为uncheck异常,也就是手动抛出这个类后,并不是必须进行抛出或者trycatch处理

public class define2 {
	public static void main(String[] args) {
		Student s = new Student();
		s.setAge(140);
		System.out.println(s.getAge());
	}
}
class Student{
	private int age;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		if(age<=0||age>=130) {
			throw new illegalAge("错误了");
		}
			this.age = age;
	}			
}

class illegalAge extends RuntimeException{
	public illegalAge() {
	
	}
	public illegalAge(String sth) {
		super(sth);
	}
}

运行结果
在这里插入图片描述

八.异常机制的实现细节

1.trycatch语句块中。可以由多个catch语句的,对多个不同的异常进行捕获

2.finally这个关键字中如果出现return等关键字程序的接下来的执行顺序问题。

public class TestReturn {
	public static int test() {
		int b = 0;
		try {
			int a = 1/0;
			return b=1;
		}catch (RuntimeException e) {
			System.out.println("出错了");
			return b=2;
		}finally {
			return b=3;
		}	
	}
	public static void main(String[] args) {
		System.out.println(test());	
	}
}

运行结果
在这里插入图片描述
只要知道finally语句块中是最后执行的就可以理解了,当try中出现异常,被catch接住,将b赋值为2,在最后跳转到finally语句块中,最后在finally语句块中返回3。
这种
在finally语句块中有return语句的会阻止catch中的return执行。

九.异常的使用原则

1.在当前方法声明中使用trycatch语句来捕获异常

2.一个方法被重写(覆盖)时,重写的方法必须抛出相同的异常或者是该异常的子类
在这里插入图片描述
3.如果父类抛出多个异常,则覆盖方法必须抛出那些异常的一个子集,不能抛出新异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值