Java异常处理

目录

前言

异常

异常处理机制

异常的表示

异常类的继承结构

Throwable类

Error类

Exception类

异常处理

try-catch语句

多个catch子句

finally子句

可嵌入的try块

抛出异常

使用throws抛出异常

使用throw抛出异常

自定义异常

创建自定义异常

最后


前言

对程序而言,发生各种各样的异常是很正常的,异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。今天我们来学习Java异常处理。

异常

在Java中,当程序执行中发生错误,错误事件对象可能导致的程序运行错误称为异常(Exception),异常可以分为3类:编译错误、运行错误和逻辑错误。

编译错误包括:大小写混淆、数据类型与变量类型不符合、使用未声明的变量。

运行错误包括:数组下标越界、除数为零。

逻辑错误包括:超出数据类型的取值范围、语句体忘记加花括号。

异常发生的原因有很多,通常包含以下几大类:

  • 用户输入了非法数据;
  • 要打开的文件不存在;
  • 网络通信时连接中断,或者JVM内存溢出。

异常产生的后果:系统中若无相应的机制处理,则会产生死机、死循环或其他对操作系统的损害。

异常处理机制

程序运行所导致的异常发生后,怎么处理异常呢?Java语言提供的异常处理机制,由捕获异常和处理异常两部分组成。

在Java程序的执行过程中,如果出现了异常事件,就会生出一个异常对象。生出的异常对象将传递给Java运行时系统,这一异常的产生和提交过程称为抛弃(Throw)异常。找到能够处理这种类型的异常的方法后,运行时系统把当前异常对象交给这个方法进行处理,这一过程称为捕获(Catch)异常。

异常的表示

Java中,所有的异常都由类来表示,例如ArithmeticException。所有异常都使用对象来描述,如ArithmeticException e。

Java中定义了很多异常类,每个异常类都代表了一种运行错误,这些异常类都是Throwable类的直接或间接子类。

异常类的继承结构

Exception类和Error类都继承与java.lang.Object中的java.lang.Throwable类。

11111111111111111111

Throwable类

Throwable是java.lang包中一个专门用来处理异常的类。只有当对象是此类或其子类的实例时,才能通过Java虚拟机或Java throw语句抛出。类似地,只有此类或其子类才可以是catch的参数类型。它有两个子类,即Error和Exception,它们分别用来处理两组异常。

Error类

一般是指与虚拟机相关的问题,表示仅靠程序本身无法恢复的严重错误,也可以理解为Error用来处理程序运行环境方面的异常。例如:系统崩溃、虚拟机出错、动态链接失败等,这一类错误无法恢复且不可捕获,这将导致应用程序中断。

Exception类

是指一些可以被捕获且可能恢复的异常情况,如数组下标越界、数值被零除、输入/输出异常等。

Exception类可以分为

  • 隐式异常:是指当程序运行时产生的异常,例如程序中除数为0引起的错误、数组下标越界错误等,这种异常是由程序本身引起的异常,但不是程序主动抛出的,而是在程序运行中产生的;
  • 显示异常:是指Java程序中的非运行时异常的处理,它们都是在程序中用语句抛出,并且也是用语句进行捕获。例如:文件没找到的异常、类没找到的引起的异常等。

Exception子类对应的处理异常方法

子类对应异常
ArithmeticException除数为0引起的异常
ArrayIndexOutOfBoundsException访问数组元素下标越界的异常
ArrayStoreException数组存储空间不够引起的异常
ClassCastException当将对象强制转换为不是实例的子类时的异常
IllegalArgumentException方法传递不合法或者不正确参数的异常
IllegalMonitorStateException监控器状态出错引起的异常
IllegalStateException在非法或不适当的时间调用方法时产生的信号的异常
IllegalThreadStateException线程没有处于请求操作所要求的适当状态时的异常
IndexOutOfBoundsException数组下标越界或字符串访问越界引起的异常
NegativeArraySizeException数组长度是负数的异常
NullPointerException当应用程序试图在需要对象的地方使用 null 时的异常
NumberFormatException字符的UTF代码数据格式有错引起的异常
SecurityException安全管理器抛出的异常,指示存在安全侵犯
StringIndexOutOfBoundsException访问字符串序号越界的异常
UnsupportedOperationException当不支持请求的操作时的异常
ClassNotFoundException未找到指定名字的类或接口引起的异常
CloneNotSupportedException当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常
IllegalAccessException拒绝访问一个类的时候抛出的异常
InstantiationException当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
InterruptedException一个线程被另一个线程中断,抛出该异常
NoSuchFieldException请求的变量不存在
NoSuchMethodException请求的方法不存在

ThreadDeath类

调用Thread类中带有零参数的stop方法时,受害线程将抛出一个ThreadDeath实例。仅当应用程序在被异步终止后必须清除时才应该捕获这个类的实例。

如果ThreadDeath被一个方法捕获,那么将它重新抛出非常重要,因为这样才能该线程真正终止,否则顶级错误处理程序不会输出消息。

虽然ThreadDeath类是“正常出现”的,但它只能是Error的子类而不是Exception的子类,因为许多应用程序捕获所有出现的Exception,然后又将其放弃。

RuntimeException类

RuntimeException是那些可能在Java虚拟机正常运行期间抛出的异常的超类。Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try...catch语句捕获它,也没有用throws​​​​​​语句声明抛出它,还是会编译通过,这种异常可以通过改进代码实现来避免。

异常处理

Java的异常处理是通过5个关键字来实现的:try、catch、throw、throws和finally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时可以通过其类型来捕获(catch)它,或最后(finally)由默认处理器来处理。

try-catch语句

异常处理的核心是try和catch,这两个关键字要一起使用。当try代码块发生异常并抛出一个异常是,异常会由相应的catch语句捕获并处理。只有在有异常抛出时,才会执行catch语句。语法格式为:

try{                            //监视
        //可能发生异常的代码
}catch(异常类型异常对象名){       //捕获并处理异常
        //异常处理代码块
}

例如:

public class myfirst {
	public static void main(String[] args) {
		int i,a;
		try {                             //监视可能发生异常的代码块
			i=0;
			a=36/i;
		}catch(ArithmeticException e) {   //捕获一个被零除异常 
			System.out.print("除数为零");
		}
	}
}

运行结果为:

除数为零

多个catch子句

当代码块

可能引起多个异常,处理这种情况时,就需要定义两个或更多的catch子句,每个子句捕获一种类型的异常。当异常被引发时,每个catch子句依次被检查,第一次匹配异常类型的子句被执行,其他的子句将被忽略。如果没有抛出异常,那么try代码块就会结束。语法格式为:

try{
        //可能发生异常的代码块
}catch(异常类型1 异常对象名1){
        //异常处理代码块1
}
catch(异常类型2 异常对象名2){
        //异常处理代码块2
}
...
catch(异常类型n 异常对象名n){
        //异常处理代码块n
}

例如:

public class myfirst {
	public static void main(String[] args) {
		try {
			int i=args.length;                //初始化i变量
			System.out.println("i="+i);       //输出i的值
			int j=5/i;                        
			int k[]= {1,2,3};                 //声明一个数组k 
			k[5]=0;                           //数组k的下标为5的元素为0
		}catch(ArithmeticException e) {
			System.out.println("被零除"+e);   //若被0除则捕获并处理
		}catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("数组越界异常:"+e);    //若发生数组越界则捕获并处理
		}
		System.out.println("执行catch块后的语句块");
	}
}

运行结果为:

i=0
被零除java.lang.ArithmeticException: / by zero
执行catch块后的语句块

finally子句

为了确保一段代码不管发生什么异常都要被执行,可以使用关键词finally来标出这样的代码块。语法格式为:

try{
        //可能发生异常的代码块
}catch(异常类型 异常对象名){
        //异常处理代码块
}
...
finally{
        //无伦是否抛出异常都要执行的代码
}

例如:

public class myfirst {
	public static void main(String[] args) {
		int i,a;
		try {                             //监视可能发生异常的代码块
			i=0;
			a=36/i;
		}catch(ArithmeticException e) {   //捕获一个被零除异常 
			System.out.print("除数为零");
		}
        finally {                         //不管发不发生异常都会被执行
			System.out.println("最后执行的语句!!");
		}
	}
}

运行结果为:

除数为零
最后执行的语句!!

可嵌入的try块

一个try代码块可以嵌入到另一个try代码块中,语法格式为:

try{                                    //外部try代码块
        try{                            //内部try代码块
        //可能发生异常的代码
        }catch(异常类型异常对象名){       //捕获并处理异常
        //异常处理代码块
        }
}catch(异常类型异常对象名){       //捕获并处理异常
        //异常处理代码块
}

抛出异常

对于处理不了的异常或要转型的异常,在方法声明除通过throws语句声明抛出异常,而throw语句是用于在方法体内抛出一个异常。

使用throws抛出异常

对于方法中可能出现的异常,如果不想在方法中进行捕获,可以在声明时利用throws语句抛出异常。声明抛出异常是在一个方法声明中的throws子句中指明。语法格式为:

[修饰符] 返回类型 方法名(参数1 参数2,...)throws异常列表{
        ...
}

例如,下面的代码声明了一个read()方法,该方法可能会抛出IOException异常。

public int read() throws IOException{
        ...
}

在throws子句中同时可以指说明该方法将不对这些异常进行处理,只是声明抛出它们,由调用此方法的其他方法负责捕获和处理。例如:下面的方法声明抛出IOException异常和IndexOutOfBoundsException异常,而不是在方法内部处理这些异常。

public static void main(String args[]) throws IOException,IndexOutOfBoundsException{
        ...
}

使用throw抛出异常

throw语句是用于在方法体中手动抛出异常,语法格式为:

throw 异常名;

throw关键字主要是用在try块中来用来说明已经发生的异常情况,throw关键字后面跟随一个从类Throwable中派生的异常对象,用来说明抛出的异常类型。例如:

import java.io.IOException;
public class myfirst {
	public static void main(String[] args) {
		try {
			System.out.println("正在运行程序.....");
			throw new IOException();   //用户自行产生异常,使用throw关键字抛出异常用户自行产生异常
		}catch(IOException e) {						//捕获异常并处理
			System.out.println("已经捕获异常");
		}
	}
}

运行结果为:

正在运行程序.....
已经捕获异常

注意:只有使用throw才会真正抛出异常,而前面将的关键字throws仅是用于方法声明,说明“可能”会产生异常,在throw语句中是如何使用new创建IOException的。这里throw抛出一个对象,所以必须为类型创建一个对象来抛出。

异常类常有方法

Exception类自己定义任何方法,它继承了Throwable提供的一些方法,所以所有异常(包括自己自定义异常),都可以获得Throwable定义的方法。同时还可以在创建的自定义异常类中覆盖一个或多个这样的方法。例如:

方法声明方法作用
public String getMessage()getMessage()方法返回描述当前异常类的消息字符串
public String toString()toString()方法返回描述当前异常类的消息的字符串
public void printStackTrace()printStackTrace()方法没有返回值,程序先后调用执行了哪些对象或类的哪些方法,使得运行过程中产生了这个异常对象

自定义异常

通过继承Exception类或它的子类,实现自定义异常类。对于自定义异常,必须采用throw语句抛出异常,这种类型的异常不会自行产生。

创建自定义异常

用户自定义异常类都必须由Exception类或Exception类的子类派生,所以必须显示指明异常类的基类。语法格式为:

class 自定义异常 extends 父异常类名{
    类体;
}

注意:

  • 自定义异常类必须是Throwable的直接或间接子类;
  • 一个方法抛出的异常是作为这个方法与外界交互的一部分而存在的;
  • 用异常代表错误,而不要在使用方法返回值。

自定义异常类的使用步骤:

  1. 创建自定义异常类;
  2. 在方法中通过throw关键字抛出异常对象;
  3. 可以使用try-catch语句捕获并处理,否则在方法声明处通过throws关键字指明要抛出给方法调用者的异常;
  4. 在出现异常方法的调用者中捕获并处理异常。

最后

好了,关于Java异常处理的知识讲到这里,谢谢观看!!!

我们下篇文章再见!!!

成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

白巧克力LIN

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

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

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

打赏作者

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

抵扣说明:

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

余额充值