【JAVA语言-第13话】异常处理 之 try-catch-finally,throws,throw关键字的详细解析

发布时间:2024年01月17日

目录

异常处理

1.1 概述

1.2 异常分类

1.3?异常处理

1.3.1 throws

1.3.2 try-catch

1.3.3 finally代码块

1.3.4 throw关键字

1.3.5 throw和throws的区别

1.4 自定义异常

1.4.1 概述

1.4.2 定义

1.4.3 自定义异常练习


异常处理

1.1 概述

????????在Java中,异常处理是一种机制,用于处理程序运行过程中可能发生的异常情况。异常是指在程序运行过程中发生的错误或意外情况,可能导致程序无法正常执行或出现不可预料的结果。? ??

1.2 异常分类

异常可以分为以下几类:

  1. 编译时异常:在代码编译过程中发生的异常,需要在编译时被捕获和处理,否则代码无法通过编译。比如语法错误、类型转换错误等。

  2. 运行时异常:在程序运行过程中发生的异常,通常是由于程序逻辑错误或意外情况导致的。运行时异常不需要强制要求在代码中显式捕获和处理,但如果不处理,会导致程序崩溃。比如除数为零错误、空指针异常等。

  3. 自定义异常:开发人员可以根据具体需求自定义异常类,用于处理特定的异常情况。自定义异常需要继承自标准异常类或其子类,并重写异常类的构造方法和其他方法。?

  4. 错误:表示程序无法恢复的严重问题,通常是由于系统错误、资源不足等情况导致的。错误无法通过捕获和处理来解决,只能通过程序终止来处理。

1.3?异常处理

????????Java中的异常处理两种方式,一是通过使用try-catch块来捕获和处理异常;try块用于封装可能会抛出异常的代码,而catch块用于捕获并处理try块中抛出的异常。二是通过throws声明在方法上,抛给外部调用的方法处理。

1.3.1 throws

格式:

????????方法声明 throws 异常类名 {

????????}

????????

说明:

? ? ? ? 使用throws处理异常,是用于方法声明上。不在方法内部处理,由外部调用的方法进行处理。处理方式仍然是try-catch或者throws。

下面是使用throws处理异常的方式,main方法后面加上throws ParseException

package com.zhy.exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class TestException {
	public static void main(String[] args) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateS = "123";
        //将字符串转换成日期时,如果dateS的格式和sdf定义的格式不一致,会抛出异常
        sdf.parse(dateS);
	}
}

1.3.2 try-catch

格式:?

????????try {

???????????????? // 可能会抛出异常的代码,只有产生异常才会走到catch块内部

????????} catch (异常类名1 变量) {

????????????????// 处理异常的代码,在工作中,一般会把异常的信息记录到一个日志中

????????}

????????……

? ? ? ? catch(异常类名n 变量名){
????????}

????????

说明:

? ? ? ? 1.try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象。

? ? ? ? 2.如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try...catch之后的代码。
? ? ? ?3.如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try...catch之后的代码。

Throwable类中定义了三个异常处理的方法:
? ? ? ? 1.String getMessage():返回此Throwable的简短描述。
????????2.String toString():返回此Throwable的详细消息字符串。
? ? ? ? 3.void printStackTrace():JVM打印异常对象,默认此方法,打印的异常信息是最全面的

下面是使用try-catch处理异常的方式,在main方法内部进行捕捉。

package com.zhy.exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class TestException {

	public static void main(String[] args) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	        String dateS = "123";
	        sdf.parse(dateS);
		}catch (ParseException e) {
			e.printStackTrace();
		}
	}
}

????????当一段代码可能引发多种异常时,可以用多个catch捕捉详细的异常类,也可以用一个catch捕捉,将异常类型提升到Exception或者Throwable

package com.zhy.exception;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.text.ParseException;
import java.text.SimpleDateFormat;

/**
 * 当代码块中可以产生多种异常,多种捕捉方式
 */
public class TestException {
	
	/**
	 * 捕捉方式一:
	 * 	使用throws声明在方法上,多个具体异常类型用逗号隔开。
	 */
	public void method1() throws ParseException, FileNotFoundException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateS = "123";
        File f = new File("d:/note.txt");
        //当字符串的格式不是日期时,会引发ParseException转换异常
    	sdf.parse(dateS);
    	//当文件不存在时,打开文件会引发FileNotFoundException文件找不到异常
    	new FileInputStream(f);
	}
	
	/**
	 * 捕捉方式二:
	 * 	使用throws声明在方法上,用异常的基类Exception接收,或者更高级别Throwable。
	 */
	public void method2() throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateS = "123";
        File f = new File("d:/note.txt");
        //当字符串的格式不是日期时,会引发ParseException转换异常
    	sdf.parse(dateS);
    	//当文件不存在时,打开文件会引发FileNotFoundException文件找不到异常
    	new FileInputStream(f);
	}
	
	/**
	 * 捕捉方式三
	 * 	使用try-catch在方法内部捕捉,多个异常用多个catch处理,对应具体的异常类型。
	 */
	public void method3() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateS = "123";
        File f = new File("d:/note.txt");
        try {
        	//当字符串的格式不是日期时,会引发ParseException转换异常
        	sdf.parse(dateS);
        	//当文件不存在时,打开文件会引发FileNotFoundException文件找不到异常
        	new FileInputStream(f);
        }catch (ParseException e) {
        	e.printStackTrace();
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 捕捉方式四:
	 * 	使用try-catch在方法内部捕捉,用一个catch处理,异常类型定义为异常基类Exception或者Throwable。
	 * @throws ParseException
	 * @throws FileNotFoundException
	 */
	public void method4(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String dateS = "123";
        File f = new File("d:/note.txt");
        try {
        	//当字符串的格式不是日期时,会引发ParseException转换异常
        	sdf.parse(dateS);
        	//当文件不存在时,打开文件会引发FileNotFoundException文件找不到异常
        	new FileInputStream(f);
        }catch (Throwable e) {
        	e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception{
		TestException e = new TestException();
		//方式一和方式二是使用throws处理异常,所以调用者要接着处理,这里处理的方式仍然是往外抛
		e.method1();
		e.method2();
		e.method3();
		e.method4();
	}
}

1.3.3 finally代码块

格式:

????????try {

???????????????? // 可能会抛出异常的代码

????????} catch (异常类名?变量) {

????????????????// 处理异常的代码,在工作中,一般会把异常的信息记录到一个日志中

????????}finally{
? ? ? ? ? ? ? ? // 无论是否出现异常都会执行,在工作中,一般用来关闭各种资源或者连接。
????????}

????????

说明:

? ? ? ? 1.finally不能单独使用,必须和try一起使用。

? ? ? ? 2.finally一般用于资源释放(IO或者JDBC),无论程序是否出现异常,都会执行

package com.zhy.exception;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestException {
	
	public Date parseTest(String dateS) {
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
	        //将字符串转换成日期时,如果dateS的格式和sdf定义的格式不一致,会抛出异常
	        sdf.parse(dateS);
		}catch (ParseException e) {
			e.printStackTrace();
		}finally {
			date = new Date();
		}
		
		return date;
	}
	
	public static void main(String[] args) {
		TestException exception = new TestException();
		//返回:当前日期
		//因为finally里面的代码无论如何都会执行,且会在try-catch后面执行;
		//所以不管传递的是什么值,是否抛出异常,parseTest方法最后返回的都是当前日期;
		//这个案例无实际意义,只是为了说明finally的执行逻辑,在工作中,一般都是用来释放IO流或者JDBC连接资源的。
		Date date = exception.parseTest("9998-12-31");
		System.out.println(date);
	}
}

1.3.4 throw关键字

格式:

????????throw new 异常类名("异常产生的原因");

????????

说明:

? ? ? ? 1.可以使用throw关键字在指定的方法中抛出指定的异常。

? ? ? ? 2.throw关键字必须写在方法的内部。

? ? ? ? 3.throw关键字后边new的对象必须是Exception类或者Exception的子类。

? ? ? ? 4.throw关键字抛出指定的异常对象,如果是运行时异常,可以不用处理;如果是编译时异常,必须采用throws或者try-catch处理异常。

1.3.5 throw和throws的区别

throws与throw这两个关键字接近,不过意义不一样,有如下区别:

  1. throws 出现在方法声明上;而throw通常都出现在方法体内。
  2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。

1.4 自定义异常

1.4.1 概述

????????java提供的异常类,有时不满足我们使用的场景时,需要自己定义一些异常类。?

1.4.2 定义

格式:

????????public class XXException extends Exception | RuntimeException{
????????????????添加一个空参数的构造方法
????????????????添加一个带异常信息的构造方法
????????}?

? ? ? ?

说明:

? ? ? ? 1.自定义异常类一般都是以Exception结尾,说明该类是一个异常类。

? ? ? ? 2.自定义异常类,必须是继承Exception或者RuntimeException。

????????????????继承Exception:那么自定义的异常类就是一个编译期异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws,要么try...catch
????????????????继承RuntimeException:那么自定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断处理)。

1.4.3 自定义异常练习

要求:

????????模拟注册操作,如果用户名已存在,则抛出异常并提示:亲,该用户名已经被注册。

步骤一:定义异常类(RegisterException.java)?

package com.zhy.exception;

public class RegisterException extends Exception{
	//1.添加一个空参数的构造方法
	public RegisterException() {
		super();
	}
	
	//2.添加一个带异常信息的构造方法:所有异常类都会有一个带异常信息的构造方法,方法内部调用父类构造,由父类处理
	public RegisterException(String message) {
		super(message);
	}
}

步骤二:测试异常类(TestException.java)

package com.zhy.exception;

import java.util.Scanner;

public class TestException {
	
	public static void main(String[] args){
		//1.使用数组保存已经注册过的用户名
		String[] userNameArray = {"张三","李四","王武","赵立","张元"};
		
		//2、使用Scanner获取用户输入的注册的用户名
		System.out.println("请输入注册的用户名:");
		Scanner sc = new Scanner(System.in);
		String username = sc.nextLine();
		
		//3.遍历存储已经注册过用户名的数组,判断用户名是否存在
		boolean isExistUser = false;
		for(int i = 0; i < userNameArray.length; i++) {
			//如果用户名已经存在,抛出RegisterException异常,告知用户“亲,该用户名已经注册!”
			if (userNameArray[i].equals(username)) {
				isExistUser = true;
				try {
					throw new RegisterException("亲,该用户名已经注册!");
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}
		//4.如果循环结束了,还没有找到重复的用户名,提示用户“恭喜你,注册成功!”
		if(!isExistUser) {
			System.out.println("恭喜你,注册成功!");
		}
	}
}

输出结果:

1.注册失败场景,抛出自定义异常。

2.注册成功场景 。

文章来源:https://blog.csdn.net/Zenghaiyue_1999/article/details/135527973
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。