欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

异常

程序员文章站 2022-05-11 14:21:46
java提供了异常处理机制:程序运行受阻时候的处理方式。 1、异常分类 Error:系统错误,由java虚拟机抛出,很少发生;免检异常 RuntimeException:程序设计错误,通常由java虚拟机抛出;免检异常 Exception的其它异常:必检异常,通过try-catch或者throws申 ......

异常

概述

Java代码在编译和运行过程中出现的不正常现象。
不正常现象分为代码可处理(异常)代码不可处理(错误) 的两种类型。
java 中使用类来对不同的异常尽享描述,使用类对象来处理异常
Java中,异常其实就是一个一个的类对象。

异常体系

Throwable
        Error: 错误, 代码不可处理的异常 (常见的错误:*Error(栈内存溢出) )
        Exception:异常 代码可以进行处理的异常(例如:NullPointerException(空指针异常))
                 RuntimeException: 运行异常 (Exception的子类)
异常
图片来源网络,侵权联系删除

异常处理

概述

对不正常现象的处理解决方案,使用代码可以继续往下执行的处理方式

方式:

1、声明异常
2、捕获异常

异常

图片来源网络,侵权联系删除

一、声明异常

概述:

遇到异常时使用关键字throws在方法中声明(参数列表后声明)异常的类型的解决异常的方式。

理解:

​ 自己遇到了异常自己不主动的去具体解决异常,而是把异常抛给下一个使用者。

代码示例:

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionDemo {
	public static void main(String[] args) throws FileNotFoundException {
		
		FileInputStream fileInputStream = new FileInputStream("a.txt");
	}

}

二、捕获异常

概述:

​ 遇到异常自己通过固定的语法捕获异常的对象,并对异常做具体的处理方案的处理方式

语法格式:

try…catch

try…catch…finally

​try…finally

1、try…catch

语法格式:
try{
	​		可能发生异常的代码段
	​	}catch(异常类型 对象名){
			处理方案
		}
解释:

​ try:尝试的意思 书写有可能发生异常的代码段

​ catch:抓住 捕获 抓住指定的具体的对象

​ catch后{ }:处理异常的方案

执行流程:

先执行try后花括号里面的代码段
       无异常:
              不需要捕获处理 直接跳过 catch继续执行下面代码
       有异常:
              catch到发生异常的位置捕获异常,直接跳到处理方案执行处理方案 执行完毕 继续执行catch外后续的代码

注意事项:

​ 1、使用该格式捕获异常的时候catch可以有多个【try代码段中可能发生几种异常,catch就可以有几个对应的异常对象的捕获】

​ 2、捕获的时候只捕获一个异常,是第一个发生的异常

​ 3、多个catch项涉及到的异常对象类型之间没有关系,书写顺序无所谓,如果有子父关系,书写的时候子类在前,父类在后
​ 4、catch捕获具体异常的时候优先使用自己对应的异常类型捕获,没有自己对应的类型使用父类类型去捕获,父类也没有放弃捕获【没有捕获处理交给jvm处理异常】
​ 5、jdk1.7版本后多个同级异常处理方案一样,可以使用一个catch语句利用逻辑或同时捕获( 使用逻辑或 |

代码示例:

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ExceptionDemo {
	public static void main(String[] args) /* throws FileNotFoundException */ {
		
		try {
			System.out.println("异常发生前");
			System.out.println(100 / 0); //算数, 这个地方在运行时会有ArithmeticException异常 
			FileInputStream fileInputStream = new FileInputStream("a.txt");
			System.out.println("异常发生后");
		} catch (FileNotFoundException | ArithmeticException e) {
			System.out.println("异常处理了");
		}catch (Exception e) {
			System.out.println("异常处理了"); //如果存在子父类关系,必须子类在前,父类在后
		
		}
		
		System.out.println("catch外后续代码");
		
	}
}


2、try…catch…finally

概述:

​ 捕获异常处理时专门执行无论是否有异常必须要执行代码的处理方式

语法格式:
try{
		​		可能发生异常的代码
		​	}catch(){
		​		异常的处理方式
		​	}....finally{
		​		必须要执行的代码	
		​	}
格式:

catch可以是一个也可以是多个

finally中的代码肯定会执行 【一般用于关闭io流对象】

注意事项:

finally不能单独使用

代码示例:

public class ExceptionDemo2 {
	public static void main(String[] args) {
		try {
			System.out.println("异常出现前");
			int num = 100 / 0;
			System.out.println(num);
			System.out.println("异常后");
		} catch (ArithmeticException e) {
			System.out.println("异常处理了");
		}finally {
			System.out.println("我一定会执行!");
		}
		
		System.out.println("try..catch外");
	}

}

3、try…finally语句

格式:
try{
	​		有异常的代码段
	​	}finally{
	​		无论是否有异常都要执行的代码
	​	}
注意:

​ 1、try中异常没有任何处理的【该使用哪种方式处理异常】

​ 2、该中格式目的不是处理异常 是支撑finally的代码执行

代码示例:

public class ExceptionDemo3 {
	public static void main(String[] args) {
		
		try {
			try {
				System.out.println("异常出现前");
				int num = 100 / 0 ;
				System.out.println(num);
				System.out.println("一场出现后");
			} catch (ArithmeticException e) {
				System.out.println("算数异常处理了");
			}
		} finally {
			System.out.println("一定会执行的代码");
		}
		
	}

}

jvm的异常处理机制

1、捕获异常的发生【异常的对象捕获到】

2、在异常发生的位置及时的停止程序的运行

3、对异常进行处理【把捕获到异常对象的信息输出到控制台】

编译异常和运行异常

编译异常:

​ 编译源代码的时候对源代码的格式和语法进行校验,不合格直接提示
​ 不允许运行,这样的异常就是编译异常

注意:

​ 编译异常必须处理【声明 和 捕获】

​ jdk中编译异常归Exception类管理

运行异常:

​ 编译通过了,运行的时候出现的不正常现象。

注意:

​ 运行异常可处理可不处理 【实际开发:一般不处理】

​ 运行异常一般归RuntimeException类管理

throw和throws

throw:抛出的意思,用于抛出一个异常对象

​ 一般用于在方法体中抛出一个具体的异常对象

​ throw意味着一定有异常,抛出的编译异常对象必须进行异常处理

​ 如果是运行异常可处理可不处理【一般不处理

throws:抛出的意思,用于声明一个异常类型

​ 一般用于方法声明后声明异常的类型,可能有异常对象,也有可能没没有异常对象。

throw和throws的比较

1、throw是对异常对象的抛出,throws是对异常类型的声明
2、throw是对异常对象实实在在的抛出,一旦使用了throw关键字,就一定有一个异常对象出现,throws是对可能出现的异常类型的声明,即使声明了一些异常类型,在这个方法中,也可能不出现任何异常
3、throw后面只能跟一个异常对象,throws后面可以跟多个异常类型


异常体系中的常用方法

Throwable是整个异常的顶层父类,定义所有异常的共性特点和功能
学习异常的功能就是Throwable的功能

构造方法:

Throwable():

创建没有任何信息的异常对象

Throwable(String message):

创建具有异常描述信息异常对象

Throwable(Throwable cause)

创建具有异常原因的异常对象

成员方法:

getCause():

获取异常对象的原因信息,也就是当前异常对象的一个成员变量

getMessage():

获取异常对象的描述信息

toString():

返回异常对象所有信息的字符串
字符串包含:名字 描述信息 异常原因】

printStackTrace():

在控制台打印异常对象的栈轨迹
jvm处理异常使用的就是这个方法

代码示例:

public class ThrowableDemo {
	public static void main(String[] args) {
		//创建没有任何信息的异常对象
		Throwable throwable = new Throwable();
		//创建具有异常描述信息异常对象
		Throwable throwable2 = new Throwable("这是一个异常");
		//创建具有异常原因的异常对象
		Throwable throwable3 = new Throwable(throwable2);
		
		//获取异常对象的原因信息
		System.out.println(throwable.getCause()); //null
		System.out.println(throwable2.getCause()); //null
		System.out.println(throwable3.getCause()); //java.lang.Throwable: 这是一个异常
		
		//获取异常对象的描述信息
		System.out.println(throwable.getMessage()); //null
		System.out.println(throwable2.getMessage()); //这是一个异常
		System.out.println(throwable3.getMessage()); //java.lang.Throwable: 这是一个异常
		
		//返回异常对象所有信息的字符串
		System.out.println(throwable.toString()); //java.lang.Throwable
		System.out.println(throwable2.toString()); //java.lang.Throwable: 这是一个异常
		System.out.println(throwable3.toString()); //java.lang.Throwable: java.lang.Throwable: 这是一个异常
		
		//在控制台打印异常对象的栈轨迹
		throwable.printStackTrace();
		throwable2.printStackTrace();
		throwable3.printStackTrace();
		//输出: 
		/*
		 * java.lang.Throwable 
		 * 		at com.ujiuye.com.ThrowableDemo.main(ThrowableDemo.java:6) 
		 * java.lang.Throwable:这是一个异常 
		 * 		at com.ujiuye.com.ThrowableDemo.main(ThrowableDemo.java:8)
		 * java.lang.Throwable: java.lang.Throwable: 这是一个异常 
		 * 		at com.ujiuye.com.ThrowableDemo.main(ThrowableDemo.java:10) 
		 * Caused by:java.lang.Throwable: 这是一个异常 
		 * 		at com.ujiuye.com.ThrowableDemo.main(ThrowableDemo.java:8)
		 */
	}
	
}

自定义异常

概述:

一般的异常jdk几乎都给提供了,但是有特殊的情况需要自己定义一个异常。

一、自定义编译异常:

步骤:
1、自定义一个类继承Exception
2、提供空参构造

代码示例:

public class DemoException extends Exception{

	//提供空参构造
	public DemoException() {
		super();
	}

	public DemoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public DemoException(String message, Throwable cause) {
		super(message, cause);
	}

	public DemoException(String message) {
		super(message);
	}

	public DemoException(Throwable cause) {
		super(cause);
	}

}

二、自定义运行异常:

步骤:
1、自定义一个类继承RuntimeException
2、提供空参构造

代码示例:

异常类1public class DemoException extends Exception{

	//提供空参构造
	public DemoException() {
		super();
	}

	public DemoException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public DemoException(String message, Throwable cause) {
		super(message, cause);
	}

	public DemoException(String message) {
		super(message);
	}

	public DemoException(Throwable cause) {
		super(cause);
	}

}

异常类2public class RunTimeException extends RuntimeException{

	public RunTimeException() {
		super();
	}

	public RunTimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public RunTimeException(String message, Throwable cause) {
		super(message, cause);
	}

	public RunTimeException(String message) {
		super(message);
	}

	public RunTimeException(Throwable cause) {
		super(cause);
	}
}

测试类:
public class Person {
	private String name;
	private int age;
	
	public Person(String name, int age) throws DemoException {
		super();
		this.name = name;
		//编译异常
		if (age > 150 || age < 0) {
			//产生异常
			throw new DemoException("你给的年龄不符");
		}else {
			this.age = age;			
		}
	}
	public Person() {
		super();
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		//运行异常
		if (age > 150 || age < 0) {
			//产生异常
			throw new RunTimeException("你给的年龄不符");
		}else {
			this.age = age;			
		}
		
	}	
}

public class TestPerson {
	public static void main(String[] args) {
		
		Person person = null;
		
		try {
			//person = new Person("张三", 200);
			person = new Person("张三", 20);
		} catch (DemoException e) {
			e.printStackTrace();
		}
		
		person.setAge(160);
	}

}

本文地址:https://blog.csdn.net/A_Zeng_/article/details/111881611