分享

开发项目中碰见异常情况怎么办?

 爱可乐的小咖 2016-08-30

开发项目中碰见异常情况怎么办?

之前讲的项目中有在接口中定义方法时,直接使用throws关键字来抛了异常,代码如下:

//读取文件中的数据

Object readData(String path)throws IOException;

//向文件中写入数据

void write(String path,Object obj)throws IOException;

记得讲到这里时,有同学提出来先在底层写怎么实现,再升级到这一步,那么今天我们就一起把throw,throws,try catch finally这些异常处理机制一起讲解一下把。

首先我们先说说如上代码中定义时直接抛异常的目的。我们通常使用的时候是有异常就直接try catch 进行处理,那这里抛出去呢,是为了交给具体子类去具体实现,这样做的好处:

  1. 1、符合我们抽象的编程思想

  2. 2、向上抽取,具体实现,这样更利于变化,具体的实现可以不一样,可以说给自己或者给客户更直观的体验。

异常有两种Error和Exception

我们一般说的异常指Exception,有两种--检查异常和未检查异常

在程序块中如果需要手动抛出一个'检查'异常用throw,

例如,throw new Exception('异常');

或者在一个try块中捕获了异常,但是在当前方法中还不想处理该异常,可以再次抛出可以用throw

throws是检查方法中的可能抛出的'未检查'异常,在写了throws的方法中可以不用去处理异常,但是在调用方法中,至少有一级是处理这种异常的.

例如

void a()throws Exception{

System.out.println(1/0);

}

void b(){

try{

a();

}catch(Exception e){

//处理异常的或者再次抛出

throw e;

}

}

void c(){

try {

b()

}catch(Exception e){

//如果在b()中再次抛出异常,可以在这里处理异常

}

}

throws是用来声明一个方法可能抛出的所有异常信息

throw则是指抛出的一个具体的异常类型。

通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。

throws通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法;

throw则需要用户自己捕获相关的异常,而后在对其进行相关包装,最后再将包装后的异常信息抛出。

对异常处理方式不同.throws对异常不处理,谁调用谁处理,throws的Exception的取值范围要大于方法内部异常的最大范围,而cathch的范围又要大于throws的Exception的范围;throw 主动抛出自定义异常类对象. throws抛出的是类,throw抛出的是对象.

在方法定义中表示的是陈述语气,第三人称单数,throw 显然要加s。(throws 一般用作方法定义的子句)

在函数体中要用throw,实际上是祈使句+强调,等价于DO throw ....,do +动词原形

throw 用于引发异常,可引发预定义异常和自定义异常。

I)异常中“throws”和“throw”的区别:

throw 是个“动词”,紧接在try语句块之后。

而throws 是“名词” ,用在函数方法名后 function A () throws Exception e {}

throw用在程序中明确表示这里抛出一个异常。throws用在方法声明的地方,表示这个方法可能会抛出某异常。

throw用来抛出实际的异常, 后面要跟一个异常对象(实例), 是一个实际的语句

throws是用来声明的, 加在方法声明的后面, 后面跟一个异常类的名字, 表示一般性动作而不是特指某一个动作.

使用throws是来说明,当前的函数会抛出一个异常。

在一般的情况下,你调用的一些函数会抛出一些异常。但是你又不想在当前的context中去处理它,就可以声明该函数会抛出该异常,这样你就不用去try-catch它了。当出现该异常,该函数会抛出此异常,让上一层的函数去处理。throws也称异常规范

public static h() throws{

try {

a.g();

}

catch(Exception e) {

throw e;

}

}

因为你没有对这个异常处理,而是简单的抛出了。

而单纯的声明

public static h() throws{

a.g();

}

也会抛出这个异常

II)try catch \throws \throw

throws如果发生了对应的错误后,下边的的确不会被执行;

try catch的理解应该辩证点看:如果catch后没有再次throw出去,那会继续执行;要想不执行必须throw处理

throws 抛出异常,解决不了再向上,直道碰到能解决这个异常的处理程序,就好像你的上司让你执行一项任务,中途你遇到问题不知道如何解决,你把问题返还给你的上司,认为既然是T分配的任务就该知道如何解决这个问题,你的上司无法解决同样把它送给经理解决,依次向上,直到有人能解决这个问题为止(不想自己另外写代码处理异常时非常有用)

try catch 则是考虑到try包含这段代码可能会遇到这种异常,直接用catch捕获处理,catch包含的代码为处理代码

throws 只是把一个异常抛出去了,如果你的上层代码有处理方式,就由上层代码来处理这个异常。

而try/catch对是清楚的知道该操作可能出现什么异常,同时在catch块中应该有处理的方法。

而且还有一种方式就是try/catch/finaly的方式。

Throws是把异常返回给调用者,由调用者处理,调用者还是要try/catch,跑不掉的

catch中就一个简单的SYSTEM.OUT.PRINTLN(…………);还有,连接数据库时会连接不上,你也不知道是驱动问题、电脑问题还是网络问题,发给用户,用户也看不懂,所以统统throws给catch,提示请与管理员联系。。。。。。这就简单多了

throws 写在方法签名后,

throw 写在方法体内,可以写在if()....

也可以catch住一个exception后立刻又把他throw 出去,什么处理也不做,还可以catch住后throw new 一个你自己定义的exception ....

throws 就是把异常抛出,但是在以后要不有个catch接受,要不就抛给主函数.就是逐级往上一级抛,直到有一个接受他的

Throws抛出异常交给调用该方法的方法 处理,即:

public class Test{

public static void main(String[] args){

Test2 test2 = new Test2();

try{

System.out.println('invoke the method begin!');

test2.method();

System.out.println('invoke the method end!');

}catch(Exception e){

System.out.println('catch Exception!');

}

}

}

class Test2{

public void method() throws Exception{

System.out.println('method begin!');

int a = 10;

int b = 0;

int c = a/b;

System.out.println('method end!');

}

}

很明显,答案出来了:

invoke the method begin!

method begin!

catch Exception!

finally语句是任选的,try语句后至少要有一个catch或一个finally,finally语句为异常处理提供一个统一的出口,不论try代码块是否发生了异常事件,finally块中的语句都会被执行

在覆盖的方法中声明异常

在子类中,如果要覆盖父类的一个方法,或父类中的方法声明了throws异常,则子类的方法也可以抛出异常,但切记子类方法抛出的异常只能是父类方法抛出的异常的同类或子类。

如:

import java.io.*;

class A {

public void methodA()throws IOException{

.....

}

}

class B1 extends A {

public void methodA()throws FileNotFoundException{

....}

}

class B2 extends A {

public void methodA()throws Exception{//Error

....}

}

public void method() throws Exception {

try {

具体程序

} catch(Exception ex) {

}

}

如果具体程序出错的话,将处理下面程序体中catch的地方,这个时候throws Exception 其实是没有意义的。

public void method() throws Exception {

try {

具体程序

} catch(FileNotFoundException ex) {

}

}

如果具体程序出错的话,且是FileNotFoundException 的情况下,将处理下面程序体中catch的地方处理。

这个时候FileNotFoundException 以外的Exception 将通过 throws Exception ,throw到上一层。

throw写在方法体内, throws写在方法名的后面

throw关键字的格式:throw new ArithmeticException(); 抛出一个异常,这些异常可以使unchecked exception(也就是RuntimeException),也可以是checked execption. throw必须有一个捕获该异常的try/catch语句

throws关键字的格式

private void arrayMethod(int[] arr)

throws ArrayIndexOutOfBoundsException,

ArithmeticException {

// Body

}

throws子句列出了方法可能抛出的异常类型,除了Error和RuntimeException异常,方法中可能抛出的异常必须在throws列表中声明,否则就会出现编译错误。

例如:假如方法中可能抛出IllegalAccessException(属于checked execption)则必须在throws列表中声明。

系统异常是默认抛出的,自己定义的异常要显示抛出。还有一些是库方法只throw 没有处理的,所以表面上你看到没有throw也catch到异常。

本文出自微信公众号mjw-java,更多内容关注微信公众号或访问www.moliying.com

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多