十五、Java中的异常


第1关:捕获异常


任务描述
本关任务:捕获程序的异常,输出异常处理的结果。

相关知识
为了完成本关任务,你需要掌握:1.如何捕获异常。

捕获异常
通过第一关我们知道,有一部分异常是需要程序员提前处理的,这种异常统一称为检测性异常,如果我们不处理,程序是不能编译通过的,在IDE中也会出现一条红线。

这个时候我们就必须处理这段可能出现异常的程序。

如何处理呢?

Java中提供了一个捕获异常的机制:try-catch

通过这两个单词的字面意思我们就能很好的理解了:try:尝试,catch:捕获;
尝试执行代码A和代码B如果这两段代码有一个出现了异常,就会执行catch中的语句,如果代码A、B都不存在异常就不会执行catch代码,最后继续执行代码C。

所以之前报错的代码我们这样写就没错啦:

在这里我们可以发现catch捕获的是FileNotFoundException,这是一个文件未找到异常,所以我们在捕获异常的时候最好要先明确异常的种类是什么。

好奇的同学可能会有疑惑,检测性异常可以用try-catch来处理,那运行时异常可不可以用try-catch来处理呢?

可不可以呢?自己验证一下吧!

编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

编辑器中的代码运行时可能会有异常,请利用本关知识处理该异常。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

输入:

4
2

输出:

2

输入:

4
0

输出:

提示:捕获异常需要用特定的类,下表总结了常用的异常类:

非检测型异常

异常 描述
ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数”除以零”时,抛出此类的一个实例。
ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常。
NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。
… …
检测性异常

异常 描述
ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
CloneNotSupportedException 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
IllegalAccessException 拒绝访问一个类的时候,抛出该异常。
InstantiationException 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
InterruptedException 一个线程被另一个线程中断,抛出该异常。
NoSuchFieldException 请求的变量不存在
NoSuchMethodException 请求的方法不存在
IOException及其子类 对文件或流的操作有误时,抛出异常
… …

代码实现

package step2;
import java.util.Scanner;
public class Task {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int num1 = sc.nextInt();
		int num2 = sc.nextInt();
		/********* Begin *********/
		 try{
		System.out.println(num1/num2);}
		catch(ArithmeticException e){
          System.out.print("除数不能为0");
		}	
		/********* End *********/
	}
}

第2关:抛出异常


任务描述
本关任务:抛出程序的异常。

相关知识
为了完成本关任务,你需要掌握:1. 如何使用throw和throws关键字。

throws 关键字
上一小节我们学习了如何处理捕获异常,但是我们有时候想偷个懒,不自己处理这些异常,可不可以呢?

答案是可以的!

我们可以将自己不想处理的异常交给别人来处理,怎么实现呢?

很简单我们只需要用throws关键字抛出该异常即可。

例如:
在这里插入图片描述

这个时候我们发现IDE报错了,提示我们这里有异常要处理,但是如果我们不想处理,就可以这样:
在这里插入图片描述

可以发现test方法内部没有报错了,但是调用test方法的地方报错了。是什么原因呢?

抛出异常,就像我们平常所说的“甩锅”,总有一个人要背锅,在Java中也一样异常最终总是要被处理或者被捕获的,所以我们如果在方法的括号后面抛出一个异常,那么该方法的调用者是必须要捕获这个异常或者将这个异常继续抛出的。

所以上面的错误就会有两种解决办法。

第一种:捕获异常:

加粗样式

第二种:把“锅”甩给Java虚拟机:

在这里插入图片描述

throw 关键字
throw关键字的作用是:主动抛出异常;

首先我们来看系统自动抛出异常:

public static void main(String[] args) {
        int a = 10;
        int b = 0;
        System.out.println(a/b);
    }

运行这段代码系统会自动抛出,java.lang.ArithmeticException异常。

这段程序使用throw关键字也可以实现:

public static void main(String[] args) {
    int a = 10;
    int b = 0;
    if(b == 0){
        throw new ArithmeticException("/ by zero");
    }
    System.out.println(a/b);
}

可以发现两段程序的运行结果都类似:
在这里插入图片描述

throw是语句抛出一个异常,一般是在代码块的内部,当程序出现某种逻辑错误时由程序员主动抛出某种特定类型的异常。

注意:使用throw关键字主动抛出检测性异常的时候,在方法名上必须使用throws表明调用这个方法可能存在要抛出的异常。

举个例子:
在这里插入图片描述
在这里插入图片描述

ArithmeticException属于运行时异常,是在运行时检测的,所以上述代码编译是能通过的,而FileNotFoundException是属于检测性异常,是在编译之前就需要处理的,所以第二段程序要加上throws才能通过编译。

在这里插入图片描述

编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

异常的抛出和处理。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。
预期输出:

该文件不存在。

代码实现

package step3;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Task {
	public static void main(String[] args)throws FileNotFoundException{	
		test();
	}
	public static void test()throws FileNotFoundException{
		File file = new File("abc");
		if(!file.exists()){		//判断文件是否存在
			//文件不存在,则 抛出 文件不存在异常
			throw new FileNotFoundException("该文件不存在");
		}else{
			FileInputStream fs = new FileInputStream(file);
		}
	}
	/********* End *********/
}

第3关:自定义异常


任务描述
本关任务:定义和使用自定义异常。

相关知识
为了完成本关任务,你需要掌握:

1.为什么要自定义异常;

2.怎么使用自定义异常。

自定义异常
前面谈到的都是系统自带的异常,但是如果我们是在开发一个复杂项目,就经常会遇到系统自带的异常不能满足我们的需求的情况,所以这个时候就需要我们自己来定义异常了。

使用自定义异常
我们一般使用继承Exception类的方式来自定义异常,那具体怎么进行呢?

很简单,我们只需要继承Exception,再将信息传递给父类就可以了:

class 自定义异常名 extends Exception{
    //因为Exception已经实现了很多异常处理的方法了属性了,
    //所以自定义异常只需要将信息传递给父类(使用super关键字)即可
}

一个简单的自定义异常:

输出:

我是自定义异常

这样就实现了一个自定义异常的定义和使用啦。

编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,具体任务如下:

定义一个自定义异常,判断用户名是否小于三位,如果用户名小于三位,就抛出一个自定义异常。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。

输入:

admin

输出:

用户名格式正确

输入:

ab

输出:

Exception in thread "main" step4.MyException: 用户名小于三位Exception at step4.Task.main(Task.java:13)

注意:因为抛出异常时会显示行号,请在13行抛出异常,否则评测可能不通过。

代码实现

package step4;
import java.util.Scanner;
public class Task {
	/********* Begin *********/
	public static void main(String[] args)throws MyException {
		Scanner sc = new Scanner(System.in);
		String username = sc.next();
		//判断用户名
		if(username.length()<3){
			throw new MyException("用户名小于三位Exception");
		}
		else{
			System.out.println("用户名格式正确");
		}
	}
}
class MyException extends Exception{
	public MyException(){}
	public MyException(String msg){
		super(msg);
	}
}
/********* End *********/
### 回答1: 可能的 Java 异常包括 NullPointerException、ArrayIndexOutOfBoundsException、NumberFormatException 等等。在 Java ,可以使用 try-catch 语句来捕捉并处理这些异常,以避免程序崩溃或出现未知错误。 ### 回答2: Java异常是指程序在运行过程出现了一些意料之外的情况或错误,导致程序无法正常运行的情况。当程序出现异常时,将会抛出一个异常对象,这个异常对象包含有关出现异常的类型及其附加信息。为了处理异常Java提供了一个异常处理机制,可以通过处理异常来避免程序崩溃或出现无法处理的错误状况。 在Java异常分为运行时异常和受检异常两种。运行时异常是那些可能会在程序运行过程异常抛出的异常,如空指针异常、数组下标越界异常等。这些异常一般是由程序逻辑错误引起的。受检异常是那些必须在编译期检查的异常,如IO异常、ClassNotFoundException等。这些异常一般是由外部因素引起的,如IO操作失败、类加载失败等。 在Java,要想处理异常,可以使用try-catch语句块。在try块包含可能抛出异常的代码,如果异常被抛出,则会跳转到catch块进行处理。catch块可以处理抛出的异常,也可以仅仅输出异常信息。此外,还可以使用finally关键字创建一个块,在程序执行完try-catch块后,无论是否抛出了异常,finally块的代码都会被执行。 在Java,还提供了异常链机制,可以将多个异常信息连接在一起,形成一条异常链。异常链可以追溯到抛出异常的原始位置,方便排查问题。此外,Java还提供了自定义异常的机制,可以根据需要创建自己的异常类型,以便更好地适应项目的需求。 总之,异常处理Java编程不可忽视的技能之一。合理运用异常处理机制可以使程序更加健壮、稳定,也可以提高程序的容错能力,减少程序的运行错误。 ### 回答3: Java是一种面向对象的编程语言,如今已经成为了世界上最受欢迎的语言之一。Java语言的异常处理机制是非常重要的一部分,它可以用来处理程序运行过程可能出现的问题,也可以让程序更加健壮和稳定。在Java,所有的异常都是通过Java异常类来表示的。在本文,我们将讨论Java异常机制及其相关知识点。 首先,我们来看Java异常的种类。Java异常分为两种:受检异常和非受检异常。受检异常是指必须在方法的throw语句声明并在调用该方法时需要处理的异常,它被称为“强制性异常”。非受检异常是指在程序运行过程会出现的错误,但并不需要在方法的throw语句明确声明的异常,它被称为“RuntimeException”。当程序出现RuntimeException时,程序的正常流程就会断,而不需要在throw语句声明。 接下来,我们来看Java异常处理机制。在Java异常的处理是通过try-catch结构来实现的。try块包含会抛出异常的代码,如果try块的代码执行没有问题,则忽略catch块。如果有异常出现,则程序会跳转到catch块进行处理。catch块需要提供异常的类型,以便对于不同的异常进行不同的处理。 在Java异常还包括了finally块。finally块包含一些无论执行流程如何都需要完成的代码,比如释放资源。无论代码是否出现异常,finally的代码都会执行。 如果在try块抛出异常后仍然需要抛出异常,我们可以使用throw语句。throw语句用于手动抛出异常,并将异常消息传递给调用方。在throw语句,我们可以使用Java定义的异常类或自定义异常类来抛出异常。 最后,让我们来看一下异常的处理。在处理异常时,我们需要清楚地知道异常的类型和异常发生的位置。我们可以使用Java的printStackTrace方法打印异常的详细信息,并根据异常的类型来选择不同的处理方式。针对受检异常,我们可以使用try-catch语句块来捕获异常;针对非受检异常,我们可以使用try-catch结构或者在方法签名使用throws语句来处理异常。 总之,Java异常处理机制是Java编程的一个非常重要的部分。在实际编程,合理的异常处理能够提高代码的可读性和可维护性,也可以让程序更加健壮和稳定。因此,我们应该重视异常处理机制的学习和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请你吃茶去

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值