博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
十一,异常的捕获与处理
阅读量:7165 次
发布时间:2019-06-29

本文共 6272 字,大约阅读时间需要 20 分钟。

hot3.png

1.异常处理格式

try...catch完整格式:

try{ 可能出现异常的语句}catch(异常类,异常对象){异常处理;}catch(异常类,异常对象){异常处理;}...finally{异常的出口; //这里的代码是肯定会被执行到的.}

2.异常处理流程

对于java来讲,每当程序出现了异常,实际上是产生了一个异常类的实例化对象.

这种处理方式非常类似于方法传参,参数匹配,则可以用次catch处理.

注:异常处理的最大父类:Throwable,但是一般开发中不会使用此种方法处理,因为其下有两个子类:

  • Error: Error一般表示JVM错误,与程序无关.

  • Exception:一般是指程序中的错误,一般开发中都用此类处理程序的异常.

一般来讲,程序开发时不要出现Throwable,因为它表示的范围太大了.

异常捕获的时候有一个原则,捕获更细的异常要放到捕获更粗的异常之前.

3.throws关键字

在程序的方法声明处可以使用throws关键字,使用此关键字的最大好处是在方法中不处理任何的异常,而交由调用处处理.

示例:

class Math{	public int div(int i,int j) throws Exception{		return i / j ;	}};public class ExceptionDemo08{	public static void main(String args[]){		Math m = new Math() ;		try{    //调用处处理异常			int temp = m.div(10,0) ;			System.out.println(temp) ;		}catch(Exception e){			e.printStackTrace() ;	// 打印异常		}	}};

如果在主方main()处使用throws关键字的话,所有异常交给最大的头JVM处理.

4.throw关键字

在程序中可以使用throw关键字人为的抛出一个异常.

示例:

public class ExceptionDemo10{	public static void main(String args[]){		try{			throw new Exception("抛着玩的") ;	// 人为抛出		}catch(Exception e){			System.out.println(e) ;		}	}};

抛出一个异常的实例化对象.

5.异常的标准化格式

示例:

class Math{	public int div(int i,int j) throws Exception{		System.out.println("======== 进行除法操作之前 ============") ;		int temp = 0 ;		try{			temp = i / j ;		}catch(Exception e){			throw e ;	// 抛出异常		}finally{			System.out.println("======== 除法操作完成之后 ============") ;		}		return temp ;	}};public class ExceptionDemo11{	public static void main(String args[]){		Math m = new Math() ;		try{			int temp = m.div(10,0) ;			System.out.println(temp) ;		}catch(Exception e){			System.out.println(e) ;		}			}};

6.RuntimeException

例如NumberFormatException就是RuntimeExcetion的子类,但是程序中可以不用try...catch来处理.

7.自定义异常

一个类只要是继承了Exception类即是自定义异常类.平时开发较少使用,大的项目开发会用到.

8.assert关键字

assert关键字表示断言,即当程序执行到某个语句之后,其结果是一个固定的值.如果断言和实际结果不符合就会抛出一个AssertException异常,开发者也可以用 assert boolean值:”string字符串”来说明断言.实际开发使用较少.

异常的补充参考资料

参考自:http://www.cnblogs.com/qinqinmeiren/archive/2010/10/14/2151702.html

Java常见异常小结

1. 异常机制

1.1 异常机制

异常机制指当程序出现错误后,程序如何处理.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器.

1.2 传统的处理异常的办法

函数返回一个特殊的结果来表示出现异常(通常这个特殊结果是大家约定俗成的),调用该函数的程序负责检查并分析函数返回的结果.这样做有如下的弊端:

①例如函数返回-1代表出现异常,但是如果函数确实要返回-1这个正确的值时就会出现混淆;

②可读性降低,将程序代码与处理异常的代码混爹在一起;

③由调用函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解.

1.3 异常处理的流程

遇到错误,方法立即结束,并不返回一个值;同时,抛出一个异常对象.调用该方法的程序也不会继续执行下去,而是搜索一个可以处理该异常的异常处理器,并执行其中的代码.

2 异常的分类

2.1 异常的分类
①异常的继承结构
基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException.
②Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked).

2.2 异常的特点

①Error体系
Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形.应用程序不应该抛出这种类型的对象(一般是由JVM抛出).如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的.所以,在进行程序设计时,应该更关注Exception体系.
②Exception体系
Exception体系包括RuntimeException体系和其他非RuntimeException的体系

A.RuntimeException

RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等.处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误.例如,可以通过检查数组下标和数组边界来避免数组越界访问异常.
B.其他(IOException等等)
这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误.

2.3 与C++异常分类的不同

Java中RuntimeException这个类名起的并不恰当,因为任何异常都是运行时出现的.(在编译时出现的错误并不是异常,换句话说,异常就是为了解决程序运行时出现的的错误). C++中logic_error与Java中的RuntimeException是等价的,而runtime_error与Java中非RuntimeException类型的异常是等价的.

3 异常的使用方法

3.1 声明方法抛出异常
语法:throws
方法是否抛出异常与方法返回值的类型一样重要.假设方法抛出异常确没有声明该方法将抛出异常,那么客户程序员可以调用这个方法而且不用编写处理异常的代码.那么,一旦出现异常,那么这个异常就没有合适的异常控制器来解决.RuntimeException与Error可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出.而已检查异常是由程序员抛出的,这分为两种情况:客户程序员调用会抛出异常的库函数(库函数的异常由库程序员抛出);客户程序员自己使用throw语句抛出异常.遇到Error,程序员一般是无能为力的;遇到RuntimeException,那么一定是程序存在逻辑错误,要对程序进行修改(相当于调试的一种方法);只有已检查异常才是程序员所关心的,程序应该且仅应该抛出或处理已检查异常.

注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常.

3.2 如何抛出异常

语法:throw
对于一个异常对象,真正有用的信息是异常的对象类型,而异常对象本身毫无意义.比如一个异常对象的类型是ClassCastException,那么这个类名就是唯一有用的信息.所以,在选择抛出什么异常时,最关键的就是选择异常的类名能够明确说明异常情况的类.
异常对象通常有两种构造函数:一种是无参数的构造函数;另一种是带一个字符串的构造函数,这个字符串将作为这个异常对象除了类型名以外的额外说明.
创建自己的异常(自定义异常):当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常.需要注意的是,唯一有用的就是类型名这个信息,所以不要在异常类的设计上花费精力.

注:捕获异常如果一个异常没有被处理,那么,对于一个非图形界面的程序而言,该程序会被中止并输出异常信息;对于一个图形界面程序,也会输出异常的信息,但是程序并不中止,而是返回用户界面处理循环中.

3.3异常处理

语法:try、catch和finally
控制器模块必须紧接在try块后面.若掷出一个异常,异常控制机制会搜寻参数与异常类型相符的第一个控制器随后它会进入那个catch 从句,并认为异常已得到控制.一旦catch 从句结束对控制器的搜索也会停止.捕获多个异常要注意语法与捕获的顺序.
注:对于Java来说,由于有了垃圾收集,所以异常处理并不需要回收内存.但是依然有一些资源需要程序员来收集,比如文件、网络连接和图片等资源.
捕获异常原则:捕捉并处理哪些知道如何处理的异常,而传递哪些不知道如何处理的异常.
再次抛出异常:在本级中,只能处理一部分内容,有些处理需要在更高一级的环境中完成,所以应该再次抛出异常.这样可以使每级的异常处理器处理它能够处理的异常.异常处理流程对应与同一try块的catch块将被忽略,抛出的异常将进入更高的一级.

4.关于异常的其他问题

①过度使用异常首先,使用异常很方便,所以程序员一般不再愿意编写处理错误的代码,而仅仅是简简单单的抛出一个异常.这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的健壮性.另外,异常机制的效率很差.
②将异常与普通错误区分开对于普通的完全一致的错误,应该编写处理这种错误的代码,增加程序的鲁棒性.只有外部的不能确定和预知的运行时错误才需要使用异常.
③异常对象中包含的信息一般情况下,异常对象唯一有用的信息就是类型信息.但使用异常带字符串的构造函数时,这个字符串还可以作为额外的信息.调用异常对象的getMessage()、toString()或者printStackTrace()方法可以分别得到异常对象的额外信息、类名和调用堆栈的信息.并且后一种包含的信息是前一种的超集.

5.常用异常:

ArithmeticException(除数为0的异常), BufferOverflowException(缓冲区上溢异常), BufferUnderflowException(缓冲区下溢异常), IndexOutOfBoundsException(出界异常), NullPointerException(空指针异常), EmptyStackException(空栈异常), IllegalArgumentException(不合法的参数异常), NegativeArraySizeException, NoSuchElementException, SecurityException, SystemException, UndeclaredThrowableException...

5.1 java.lang.NullPointerException

异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,即把数组的初始化和数组元素的初始化混淆起来了.数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话).
5.2 java.lang.ArrayIndexOutOfBoundsException
异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常.
5.3 java.lang.IllegalArgumentException
这个异常的解释是"方法的参数错误",比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误.
5.4 java.lang.IllegalAccessException
这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常.对程序中用了Package的情况下要注意这个异常

异常跟普通的警告等有一定的区别.当应用程序发生异常时,会中断正在执行的程序的正常指令流.也就是说,发生异常后面的代码将得不到正确的执行.甚至还会触发数据库的回退操作.在Java开发平台中,异常包括预定义异常与自定义异常.这两种异常的类型互为补充.作为一个合格的程序开发人员,要善于在应用程序中使用异常.这可以提高应用程序的交互性.

20150416

JAVA学习笔记系列

--------------------------------------------

                    联系方式

--------------------------------------------

        Weibo: ARESXIONG

        E-Mail: aresxdy@gmail.com

------------------------------------------------

转载于:https://my.oschina.net/u/2288529/blog/402159

你可能感兴趣的文章