黑马程序员技术交流社区

标题: 异常处理throws、throw、try catch这三者的区别 [打印本页]

作者: 王晓东    时间: 2012-6-3 09:54
标题: 异常处理throws、throw、try catch这三者的区别
我是个菜鸟,我一直没有搞懂throws、throw、try catch这三者的区别
作者: 黄捷    时间: 2012-6-3 09:57
关键字:throw  throw是一种控制程序流程的特殊方法而已。没有相应的catch的话,可以中 止当前的方法继续执行。
关键字:throws  声明方法时 候,如果不声明throws的话,那么一般的Exception都要在这个 方法中终结,也就是说一定要有相应的catch处理,否则编译时会产生错误。如果方法声明了throws的 话,可以交给上一级方法去处理。以此类推。但是 有些Exception可以不加捕捉,编译也会通过。继承Exception类, 可以自己定义Exception,对于特定的状态,用throw抛出专用 的例外。这对于特定的middle ware开发,有一定帮助。
关键字:try、catch  用 个形象的比喻,如果说throws相当于职业介绍中介的话,那try和 catch就 是一对倒霉的打工仔。很有意思,throws只是告诉编译器--方法可能产生的异常问题,然后把问题处理抛给try和catch。 他们一个负 责发现异常关系,一个负责异常捕获。
作者: 张少威    时间: 2012-6-3 09:58
throws是用来声明一个方法可能抛出的所有异常信息
throw则是指抛出的一个具体的异常类型。
通常在一个方法(类)的声明处通过throws声明方法(类)可能抛出的异常信息,而在方法(类)内部通过throw声明一个具体的异常信息。
throws通常不用显示的捕获异常,可由系统自动将所有捕获的异常信息抛给上级方法;
throw则需要用户自己捕获相关的异常,而后在对其进行相关包装,最后在将包装后的异常信息抛出。
作者: 杜俊彪    时间: 2012-6-3 09:59
我觉得这份总结的很好,很有用的,    看看吧!!
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到异常
作者: 龙秋地    时间: 2012-6-3 10:38
本帖最后由 龙秋地 于 2012-6-3 10:40 编辑

try
{
    需要被检测的代码
}
catch(异常类 变量名)
{
    处理异常的代码: (处理方式)
}
finally
{
    一定会执行的语句;
}



*/
  1. //记住一点:catch是用于处理异常.
  2. //如果没有catch就代表异常没有被处理过.如果该异常是检测时异常.
  3. //那么必须声明.(throws)
  4. class  Demo
  5. {
  6.         try
  7.         {
  8.                 throw new Exception();
  9.         }
  10.         finally ()
  11.         {
  12.                 //关闭资源
  13.         }
  14. }
复制代码
throw
throws:在函数上声明异常便于提高安全性,让调用出进行处理.不处理编译失败
throw和throws的区别:
throws使用在函数上.
throw使用在函数内
throws后面跟的是异常类.可以跟多个,用逗号隔开.
throw后跟的是异常对象.
异常的处理原则:
1.处理方式有两种:try或者throws
2.调用到抛出异常的功能时,抛出几个,就处理几个.
一个try对应多个catch
3.多个cathch,父类的catch放最下面
4.catch内,需要定义针对性的处理方式,不要简单地定义printStackTrace,输出语句.
也不要不写.
当捕获到的异常,本功能处理不了时,可以继续在catch中抛出.
作者: 胡团乐    时间: 2012-6-3 10:43
        throws用在方法的大括号前面如 public static void main() throws Exception{...抛出异常 让继承者,实现着,调用者去处理
        try{这里存放会抛出异常的代码}
        catch(Exception e){这里需要作出处理动作 一般打印友好的信息,不让用户看到异常的具体信息 这里面会用到throw 比如 throw new RuntimeExcption("这儿有异常")如果抛出异常 而后面没写finally方法 程序会终止}
        finally{这里存放一定会执行的代码 比如一些 io流的关闭操作和数据库对象的关闭操作等}
}

代码示例:
public void method()throws Exception
{
        连接数据库;
        数据操作;//throw new SQLException();
        关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。
        try
        {
                连接数据库;
                数据操作;//throw new SQLException();
        }
        catch (SQLException e)
        {
                会对数据库进行异常处理;
                throw new Exception();
        }
        finally
        {
                关闭数据库;
        }
}


作者: 李春阳    时间: 2012-6-3 17:09
各关键字作用:
throws ----- 声明异常
throw ----- 抛出异常
try ----- 捕捉异常
catch ----- 报出异常执行的操作
finally  必须执行的代码
以上是学术解释~下面再简单的做个比喻。

比如我们要执行这么一个过程:
小明去打酱油。

那么,这个过程会有一些意外、异常。比如:打酱油钱不够,打酱油钱被小明丢了。

于是乎咱就有俩解决方法:一、不理会~将烦恼抛出脑后,就是throws所有异常。
                                     爱谁谁~丢钱不顾钱我不管了~
                        二、测试执行这个过程(try),然后呢捕捉(catch)其中的意外进行处理~但最终不管任何阻挠,一定还要执行(final)一些步骤:比如说回家~
                                                        钱不够?问题抛给他妈,找你妈拿;     钱丢了?直接打一顿~

二比较复杂,以代码形式写出来哈:
try
{
     小明去打酱油;
}
catch(打酱油钱不够 e1)
{
     我也没钱;
     throw new 留给你妈解决的问题();
}
catch(打酱油钱丢了 e2)
{
     直接打一顿;
}
finally
{
     小明回家;
}
作者: 韩国军    时间: 2012-6-3 17:35
异常的捕获和处理
    Java异常的捕获和处理是一个不容易把握的事情,如果处理不当,不但会让程序代码的可读性大大降低,而且导致系统性能低下,甚至引发一些难以发现的错误。
    Java异常处理涉及到五个关键字,分别是:try、catch、finally、throw、throws。下面将骤一介绍,通过认识这五个关键字,掌握基本异常处理知识。
1、 异常处理的基本语法
在java中,异常处理的完整语法是:
try{
//(尝试运行的)程序代码
}catch(异常类型 异常的变量名){
//异常处理代码
}finally{
//异常发生,方法返回之前,总是要执行的代码
}
以上语法有三个代码块:
try语句块,表示要尝试运行代码,try语句块中代码受异常监控,其中代码发生异常时,会抛出异常对象。
    catch语句块会捕获try代码块中发生的异常并在其代码块中做异常处理,catch语句带一个Throwable类型的参数,表示可捕获异常类型。当 try中出现异常时,catch会捕获到发生的异常,并和自己的异常类型匹配,若匹配,则执行catch块中代码,并将catch块参数指向所抛的异常对 象。catch语句可以有多个,用来匹配多个中的一个异常,一旦匹配上后,就不再尝试匹配别的catch块了。通过异常对象可以获取异常发生时完整的 JVM堆栈信息,以及异常信息和异常发生的原因等。
finally语句块是紧跟catch语句后的语句块,这个语句块总是会在方法返回前执行,而不管是否try语句块是否发生异常。并且这个语句块总是在方法返回前执行。
2、 try、catch、finally三个语句块应注意的问题
    第一、try、catch、finally三个语句块均不能单独使用,三者可以组成 try...catch...finally、try...catch、try...finally三种结构,catch语句可以有一个或多个,finally语句最多一个。
第二、try、catch、finally三个代码块中变量的作用域为代码块内部,分别独立而不能相互访问。如果要在三个块中都可以访问,则需要将变量定义到这些块的外面。
第三、多个catch块时候,只会匹配其中一个异常类并执行catch块代码,而不会再执行别的catch块,并且匹配catch语句的顺序是由上到下。
3、throw、throws关键字
    throw关键字是用于方法体内部,用来抛出一个Throwable类型的异常。如果抛出了检查异常,则还应该在方法头部声明方法可能抛出的异常类型。该 方法的调用者也必须检查处理抛出的异常。如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。如果抛出 的是Error或RuntimeException,则该方法的调用者可选择处理该异常。有关异常的转译会在下面说明。
    throws关键字用于方法体外部的方法声明部分,用来声明方法可能会抛出某些异常。仅当抛出了检查异常,该方法的调用者才必须处理或者重新抛出该异常。 当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣一般在catch块中打印一下堆栈信息做个勉强处理。下面给出一个简单例子,看看如何 使用这两个关键字:
public static void test3() throws Exception{
//抛出一个检查异常
throw new Exception("方法test3中的Exception");
}
4、 Throwable类中的常用方法
getCause():返回抛出异常的原因。如果 cause 不存在或未知,则返回 null。
getMessage():返回异常的消息信息。
printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值。


作者: 王月    时间: 2012-6-3 20:12
四楼好给力啊,lz把那个弄懂,异常这里估计就没问题了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2