黑马程序员技术交流社区

标题: 异常处理问题 [打印本页]

作者: wodeairenw    时间: 2013-3-7 12:47
标题: 异常处理问题
建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句e.printSrackTrace().
也不要简单的就书写一句输出语句。

我想问实际开发中到底是如何具体的处理异常的?catch到底需要如何写?
作者: 邹学良    时间: 2013-3-7 12:57
在处理异常前,先让我们了解下什么是JAVA异常:
在JAVA异常分为三类:
        第一类是Error,Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。Error是一种unchecked Exception,编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常;一般情况下,在程序中也不应该抛出Error类型的异常。
        第二类是RuntimeException, RuntimeException 是一种unchecked Exception,即表示编译器不会检查程序是否对RuntimeException作了处理,在程序中不必捕获RuntimException类型的异常,也不必在方法体声明抛出RuntimeException类。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去捕获RuntimeException。
        第三类是一般的checked Exception,这也是在编程中使用最多的Exception,所有继承自Exception并且不是RuntimeException的异常都是checked Exception,如图1中的IOException和ClassNotFoundException。JAVA 语言规定必须对checked Exception作处理,编译器会对此作检查,要么在方法体中声明抛出checked Exception,要么使用catch语句捕获checked Exception进行处理,不然不能通过编译。checked Exception用于以下的语义环境:

A: 该异常发生后是可以被恢复的,如一个Internet连接发生异常被中止后,可以重新连接再进行后续操作。
B: 程序依赖于不可靠的外部条件,该依赖条件可能出错,如系统IO。
C: 该异常发生后并不会导致程序处理错误,进行一些处理后可以继续后续操作。

那么我们在JAVA异常处理中的需要注意那些事项呢?
合理使用JAVA异常机制可以使程序健壮而清晰,但不幸的是,JAVA异常处理机制常常被错误的使用,下面就是一些关于Exception的注意事项:

1. 不要忽略checked Exception
请看下面的代码:
try
{
  method1();  //method1抛出ExceptionA
}
catch(ExceptionA e)
{
    e.printStackTrace();
}
上面的代码似乎没有什么问题,捕获异常后将异常打印,然后继续执行。事实上在catch块中对发生的异常情况并没有作任何处理(打印异常不能是算是处理异常,因为在程序交付运行后调试信息就没有什么用处了)。这样程序虽然能够继续执行,但是由于这里的操作已经发生异常,将会导致以后的操作并不能按照预期的情况发展下去,可能导致两个结果:
一是由于这里的异常导致在程序中别的地方抛出一个异常,这种情况会使程序员在调试时感到迷惑,因为新的异常抛出的地方并不是程序真正发生问题的地方,也不是发生问题的真正原因;
另外一个是程序继续运行,并得出一个错误的输出结果,这种问题更加难以捕捉,因为很可能把它当成一个正确的输出。
那么应该如何处理呢,这里有四个选择:

(1) 处理异常,进行修复以让程序继续执行。
(2) 重新抛出异常,在对异常进行分析后发现这里不能处理它,那么重新抛出异常,让调用者处理。
(3) 将异常转换为用户可以理解的自定义异常再抛出,这时应该注意不要丢失原始异常信息(见5)。
(4) 不要捕获异常。

因此,当捕获一个unchecked Exception的时候,必须对异常进行处理;如果认为不必要在这里作处理,就不要捕获该异常,在方法体中声明方法抛出异常,由上层调用者来处理该异常。

2. 不要一次捕获所有的异常
请看下面的代码:
try
{
  method1();  //method1抛出ExceptionA
    method2();  //method1抛出ExceptionB
    method3();  //method1抛出ExceptionC
}
catch(Exception e)
{
    ……
}
这是一个很诱人的方案,代码中使用一个catch子句捕获了所有异常,看上去完美而且简洁,事实上很多代码也是这样写的。但这里有两个潜在的缺陷,一是针对try块中抛出的每种Exception,很可能需要不同的处理和恢复措施,而由于这里只有一个catch块,分别处理就不能实现。二是try块中还可能抛出RuntimeException,代码中捕获了所有可能抛出的RuntimeException而没有作任何处理,掩盖了编程的错误,会导致程序难以调试。
下面是改正后的正确代码:
try
{
  method1();  //method1抛出ExceptionA
    method2();  //method1抛出ExceptionB
    method3();  //method1抛出ExceptionC
}
catch(ExceptionA e)
{
    ……
}
catch(ExceptionB e)
{
    ……
}
catch(ExceptionC e)
{
    ……
}

作者: scott0610    时间: 2013-3-7 12:59
Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。
在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,
调用这个对象的方法可以捕获到这个异常并进行处理。
Java的异常处理是通过5个关键词来实现的:try、catch、throw、throws和finally。
一般情况下是用try来执行一段程序,如果出现异常,系统会抛出(throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。
用try来指定一块预防所有"异常"的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的"异常"的类型。
throw语句用来明确地抛出一个"异常"。
throws用来标明一个成员函数可能抛出的各种"异常"。
finally为确保一段代码不管发生什么"异常"都被执行一段代码。

在实际开发中只需要对异常进行捕捉。一般在catch代码块中通过getMessage()方法或者printStackTrace()方法查看异常信息。
getMessage()方法用来得到有关异常事件的信息。
printStackTrace()方法是用来跟踪异常世界发生事的堆栈信息。
我们主要关注这些信息的名字和行号就能很快知道怎么解决。


希望对你有所帮助。

作者: 聂斌    时间: 2013-3-7 13:02
catch里面定义代码的原则是:
一般自己能解决的问题尽量自己解决,,你可以在catch里面定义任意的代码,比如你还可以在写个try catch,
自己确实无法处理的就抛出去,或者这个异常是无法解决的就抛RuntimeException异常,直接让 程序终止





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