Java异常处理机制

异常处理Exception

1、什么是异常处理?

异常是指程序在运行过程中出现的非正常现象,例如用户输入错误、除数为零、读取的文件不存在、数组下标越界等。发生异常时,程序终止运行。

示例1:

public class Demo1 {
    public static void main(String[] args) {
		int i=1,j=0,res;
		System.out.println("begin");
		res =i/j;
		System.out.println("end");
	}
}

结果:

begin
Exception in thread “main” java.lang.ArithmeticException: / by zero
at shiyizhang.Demo1.main(Demo1.java:7)

1.1异常处理流程

  1. 上述代码会抛出异常,原因是0不能作为除数

  2. 当程序运行前或者运行期间发生了异常,那么JVM如何处理异常呢?

    (1)Java对运行前和运行期间可能发生的异常进行了预定义,Java定义了很多与异常相关的类,这些类 都是以Exception结尾的,每个异常类来表示一个特定的异常,比如算术异常用ArithmeticException类来 表示,用NullPointerExcetion表示空指针异常。

    (2)当异常发生时,此时JVM就会自动创建异常类的对象,JVM会将这个异常对象用throw语句将异常对象抛出,抛出的目的是让开发者知道程序发生了异常,开发者重新修改代码,使得代码正确运行。

  3. 当程序发生异常时,程序就终止运行了。

    异常处理是为了消除程序中的异常,保证程序中没有异常,进而保证程序能够继续运行。

2、Java异常体系结构

4UtXNV.png

(1)Error类:表示仅靠程序本身无法恢复的严重错误,如内存溢出、动态链接失败、虚拟机错误。

(2)Exception类:由java应用程序抛出和处理的非严重错误,如所需文件找不到、算数运算出错等。Exception可分为两大类:

运行时异常:也叫unchecked异常,包括RuntimeException及其子类。不要求程序必须处理它们。

设计时异常:也叫checked异常:除了运行时异常外的其他从Exception类继承的异常类。

常见的异常类:

异常类名异常分类说明
Exception设计时异常异常层次结构的根类
IOExceptin设计时异常IO异常的根类,属于非运行时异常
FileNotFoundException设计时异常文件操作时,找不到文件。属于非运行时异常。
RuntimeException运行时异常运行时异常的根类,RuntimeException及其子类,不要求必须处理
ArithmeticException运行时异常算数运算异常,比如:除数为零
IllegalArgumentException运行时异常方法接收到非法参数,属于运行时异常
ArrayIndexOutOfBoundsException运行时异常数组越界访问异常,属于运行时异常
NullPointerException运行时异常尝试访问null对象的成员时发生的空指针异常,属于运行时异常
ArrayStoreException运行时异常数据存储异常,写数组操作时,对象或数据类型不兼容
ClassCastException运行时异常类型转换异常
IllegalThreadStateException运行时异常试图非法改变线程状态,例如试图启动一已经允许的线程
NumnerFormatException运行时异常数据格式异常,试图把一字符串非法转换成数值

2.1 错误与异常的区别

错误是Error(JVM错误,内存溢出、虚拟机错误等)

异常是Exception

错误无法通过代码编写解决问题,Exception可以通过try-catch-finally或者通过throw,trows解决。

3、Java异常处理机制

处理异常的两种办法:

使用try-catch-finally

使用throws-throw

3.1 使用try-catch处理异常

示例2:

4UR6G4.png

运行结果:

begin
catched
java.lang.ArithmeticException: / by zero
over
at shiyizhang.Demo2.mm(Demo2.java:10)
at shiyizhang.Demo2.main(Demo2.java:4)

分析:

1、try块中存放可能发生异常的代码

2、catch块存放处理异常的代码

3、当try块中发生异常时,程序立即跳转到catch块运行,catch块的作用是捕获异常,当异常被捕获以后,异常就没有了,所以程序就可以继续运行了。

4、如果try块中没有发生异常,那么程序就不会进入catch块。

catch语句块中可以加入用户自定义处理信息,也可调用异常对象的方法输出异常信息,常用方法如下:

printStackTrace():输出异常堆栈信息,该方法打印出的跟踪信息可以分析方法的调用过程,错误一定是发生在从上到下寻找到的第一个自定义的类。

getMessage():返回异常信息描述字符串,描述异常产生的原因。

3.2 使用try-catch-finally处理异常

无论try快中是否发生异常,finally语句块中的代码总能执行。finally的作用是用于回收系统资源,比如释放数据库连接,断开网络等。

示例3:

4UgeoD.png

运行结果:

begin
catched
java.lang.ArithmeticException: / by zero
finally
over
at shiyizhang.Demo3.main(Demo3.java:8)

3.3 使用多重catch处理异常

一段代码可能回引发多种类型的异常,这时可以在一个try语句块之后加多个catch语句块处理不同的异常。但是排列顺序必须是从子类到父类,最后一个一般都是Exception类。因为如果父类在前,那么后面catch语句块将不会被执行。

示例4:

4U2QNF.png

运行结果:

begin
java.lang.ArithmeticException: / by zero
错误原因:/ by zero
catched
finally
over
at shiyizhang.Demo4.main(Demo4.java:10)

3.4 使用throws和throw抛出异常

如果程序本身没有错误,但是数据不符合业务要求,此时开发人员可以自己抛出异常对象。此时应该使用throws和throw配合实现抛出异常。

示例5:

class Person{
	private String name;   //姓名
	private int age =0;
	private String gender ="男"; //性别
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	
	public void setGender(String gender)throws Exception{
		if ("男".equals(gender) ||"女".equals(gender)) {
			this.gender =gender;
		}else {
			throw new Exception("性别必须是男或女");
		}
	}
	public void print() {
		System.out.println("姓名:"+this.getName()+",性别:"+getGender()+",年龄"+getAge());
	}
}
public class Demo5 {
	public static void main(String[] args) {
		Person person =new Person();
		try {
			person.setName("钟小馗");
			person.setAge(10);
			person.setGender("nv");
			person.print();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行结果:

java.lang.Exception: 性别必须是男或女
at shiyizhang.Person.setGender(Demo5.java:27)
at shiyizhang.Demo5.main(Demo5.java:40)

3.4.1 throws和throw的区别

(1)throw用于程序员自行抛出异常,throws用于声明该方法内抛出异常。

(2)throw必须用在方法内部,表示抛出异常,可以作为单独语句使用;throws必须用在方法声明的后面,不能单独使用。它表示告诉调用者,该方法可能发生什么样的异常,而主调方法需要处理这个异常。在被调方法中使用throw和throws,而在主调方法中使用try-catch捕获异常。

(3)throw抛出一个异常对象,只能是一个;throws后面跟异常类,可以跟多个。

特殊情况:

示例6:

public class Demo6 {
	public static void main(String[] args) throws ArithmeticException {
		int i=1, j = 0;
		System.out.println("begin");
		int result = i/j;
		System.out.println("end");
	}
}

异常抛给JVM了,由JVM处理异常。

3.5 自定义异常

当jdk中的异常类不能满足需求时,可以自定义异常类。

示例7:

class GenderException extends Exception{
	public GenderException(String gender) {
		super(gender);
	}
}
class Person{
	private String name;   //姓名
	private int age =0;
	private String gender ="男"; //性别
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	
	public void setGender(String gender)throws GenderException{
		if ("男".equals(gender) ||"女".equals(gender)) {
			this.gender =gender;
		}else {
			throw new GenderException("性别必须是男或女");
		}
	}
	public void print() {
		System.out.println("姓名:"+this.getName()+",性别:"+getGender()+",年龄"+getAge());
	}
}
public class Demo7 {
	public static void main(String[] args) {
		Person person =new Person();
		try {
			person.setName("钟小馗");
			person.setAge(10);
			person.setGender("nv");
			person.print();
			
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("异常原因是:"+e.getMessage());
		}
	}
}

运行结果:

异常原因是:性别必须是男或女
java.lang.Exception: 性别必须是男或女
at shiyizhang.Person.setGender(Demo5.java:27)
at shiyizhang.Demo7.main(Demo7.java:10)

3.6 异常链

在处理异常时,有时候会出现A方法调用B方法,B方法抛出了异常,A方法会继续抛出这个异常。

4UIZPf.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值