java基础(十四)异常处理

1.1 引言

要点:异常是运行时错误。异常处理使得程序可以处理运行时错误,并且继续通常的执行。

在程序运行过程中,如果JVM检测出一个不可能执行的操作,就会出现运行时错误(例如,使用一个越界的下标访问数组等)。在Java中,运行时错误会作为异常抛出。异常就是一种现象,表示阻止正常运行的错误或情况。如果异常没有被处理,那么程序将会非正常终止。那么如何处理异常使得程序可以继续运行或者优雅的终止呢?

1.2 异常处理概述

要点:异常是从方法抛出的。方法的调用者可以捕获以及处理该异常。

第一种方法是使用逻辑,判断可能出现的错误(例如:除数为0),给出提示(提示语)以及接下来的操作(放入循环中重新输入或结束输入)

第二种就是我们的异常机制了。

方法如何通知它的调用者一个异常产生了呢?Java可以让一个方法抛出一个异常,该一场可以被调用者捕获和处理。如下例:

import java.util.Scanner;

public class QuotientWithException{
	public static int quotient(int number1,int number2) {
		if(number2==0) {
			throw new ArithmeticException("Divisor cannot be zero");//异常类创建的异常对象并抛出,调用catch块
		}
		return number1/number2;
	}
	
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("Enter two Integers: ");
		int number1 = input.nextInt();
		int number2 = input.nextInt();
		try {
		int result = quotient(number1,number2);//这里面可能要抛出异常
		System.out.println(number1+" / "+number2+" is "+result);
		}catch(ArithmeticException ex){
			System.out.println("Divisor cannot be zero");//异常处理办法
		}
		
		System.out.println("OK~");
	}
}

这样编译器就不会报错,而是当发生指定的动作抛出指定错误类型而后执行你指定的动作。

1.3 异常类型

要点:异常是对象,而对象都采用类来定义,异常的根类是java.lang.Throwable.可以通过继承Exception或者其子类来创建

这些异常类可以分为三种主要类型:系统错误、异常和运行时异常。

(1)系统错误

系统错误(System Error)是由Java虚拟机抛出的,用Error类(内部系统错误)表示,这样的错误很少发生,如果发生,除了通知用户以及尽量稳妥地终止程序外,几乎什么也不能做。

(2)异常(Exception)

异常是用Exception类表示的,它描述的是由你的程序和外部环境所引起的错误,这些错误能被程序捕获和处理。

(3)运行时异常(Runtime Exception)是用RunTimeException类表示的,它描述的是程序设计错误,例如错误的类型转换等。

Runtime Exception、Error以及它们的子类都称为免检异常。所有其他异常都称为必检异常,编译器强制程序员检查并通过try—catch块处理它们。

 

2.1 关于异常处理的更多讨论

要点:异常的处理器是通过当前的方法开始,沿着方法调用链,按照异常的反向传播方向找到的。

Java的异常处理模型基于三种操作:声明一个异常、抛出一个异常和捕获一个异常。

 

2.1.1 声明异常

每个方法都必须声明它可能抛出的必检异常的类型。这称为声明异常。除了Error和RuntimeException,其他异常都必须在方法头中显式声明。这样方法的调用者才会被告知有异常。

在方法中声明一个异常,就要在方法头中使用关键字throws:

public void myMethod() throws IOException,Exception2,...n

关键字throws表明mvMethod,可能会抛出它后面的那些异常列表里的异常

注意:如果父类中的方法没有声明异常,那么就不能在子类中对其重写时声明异常

 

2.1.2 抛出异常

检测到错误的程序可以创建一个合适的异常类型的实例并抛出它,这称为抛出一个异常。

IllegalArgumentException ex = new IllegalArgumentException ("Wrong Argument");//异常描述信息可选

throw ex;

或者 

throw new IlleagalArgumentException("Wrong Argument");

注意:声明异常的关键字是throws,抛出异常的关键字是throw

 

2.1.3 捕获异常

当抛出一个异常时,可以在try—catch块中捕获或处理它。如果try块中的某条语句抛出一个异常,Java就会跳过try中剩余的语句,然后开始查找处理这个异常的代码。处理这个异常的代码称为异常处理器,可以从当前方法开始,沿着方法调用链,按照异常的反向传播方向找到这个处理器。从第一个到最后一个逐个检查catch块,判断在catch块中的异常类实例是否是该异常对象的类型,如果是,就将该异常对象赋值给所声明的变量。然后执行catch中的代码。如果没有发现异常和其处理器,Java就会退出这个方法,然后把异常传给这个方法的调用者。父类的异常类型也必须比子类的异常类型范围大。

 

2.1.4 从异常中获取信息

2.1.5 finally字句

要点:无论异常是否发生,finally字句总会被执行

有时候,无论异常是否发生,都希望执行某些代码,Java的finally字句可以用来实现这个目的。

语法结构:

	try {
		statements;
	}catch(TheException ex){
		handling ex;
	}
	finally {
		finalStatements;
	}

 三种情况:(1)try中没有异常(2)try中有异常被捕获(3)try中有一场没有被捕获

上面三种情况finally块均执行。

2.1.6 何时使用异常

要点:当错误需要被方法的调用者处理的时候,方法应该抛出一个异常。

try块包括正常情况下执行的代码,catch块下是异常情况需要处理的代码,异常处理将错误处理代码从正常的编程任务中分离出来,但由于异常处理需要沿着方法调用链来传播异常,所以需要更多的时间和资源。应该创建一个异常对象并抛出,如果能在发生异常的方法中处理异常,那么就不需要抛出或使用异常。

一般来说,一个项目中多个类都会发生的共同异常应该考虑设计为一个异常类。对于简单错误,最好进行局部处理(if-else),无须抛出异常,当必须处理不可预料的错误状况时应使用try-catch,否则用逻辑测试去处理,不要轻易浪费系统资源。

2.1.7 重新抛出异常

要点:如果异常处理器不能处理一个异常,或者只是简单地希望它地调用者注意到该异常,Java允许该异常处理器重新抛出异常。

try{

statements;

}catch{TheException ex}{

perform operations before exits;

throws ex;

}

语句throw ex重新抛出异常给调用者,以便调用者的其他处理器处理异常ex的机会。

2.1.8 链式异常

要点:与一个异常一起抛出一个异常,构成链式异常。

	public static void main(String args[]) {
		try {
			method1();
		}
		catch(Exception ex){
			ex.printStackTrace();
		}
	}
	
	public static void method1() throws Exception{
		try {
			method2();
		}catch(Exception ex) {
			throw new Exception("new Info from method2",ex);
		}
	}
	
	public static void method2() throws Exception{
		throw new Exception("new Info from method1");
	}

method1方法把method2方法的异常包装成了崭新的异常,新异常被抛出,在main中被捕获,进行打印,先打印新异常,在打印meithod2中的原始异常。

2.1.9 创建自定义异常

要点:可以通过继承java,lang,Exception类来定义一个自定义异常类。

因为Java已经提供了相当多的异常类,那么尽量使用它们,如果遇到不能用预定义类来充分描述问题,那么就可以通过集成类来创建自己的异常类。

public class InvalidRadiusException rxtend Exception{
    private double radius;    
    public InvalidRadiusException (double radius){
        super("Invalid radius"+radius);
        this.radius = radius;
    }
}

其中是重写了父类的异常信息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值