现在的位置: 首页 > 综合 > 正文

Java Excetion 处理

2013年09月27日 ⁄ 综合 ⁄ 共 14171字 ⁄ 字号 评论关闭

总结:

0.Java  Throwable  :  

1.异常的四种处理


  1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。

  2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。

  3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。

  4、不要捕获异常。

2. 处理异常的具体原则

1).不要用一个catch Exception来处理所有的exceptions。

2).不同的Exception 要分不同的catch ,做不同的处理

3).先catch子的Exception,再catch父的Exception,否则就子Exception catch 不到

4).自己能处理的Exception才catch ,不能处理的就抛出

5).抛出异常是, 如果期待客户端做具体处理,抛出checked exception,否则抛出unchecked exception。

6).在程序最高层对所有exception做处理,对于runtimeexception,log后继续抛出。

7).不要自己的些没有意义的异常

8).不要写过于庞大的try块

9).是否所有的Exception都要處理?

原則上是的。只要用到的method有宣告throws SomeException,則呼叫該method的地方,就要使用try {} catch(SomeException)的語法。當然像是try {} catch(SuperClassOfSomeException)的用法也行。唯一的例外是java.lang.RuntimeException及其子類別可以不必處理。

哪些屬於RuntimeException呢?像是ArrayIndexOutOfBoundException就是其中之一,它發生在陣列索引不合法的情況下:

public class Test {
    public static void main(String[] argv) {
        int[] x = new int[10];
        x[100] = 0; // will generate ArrayIndexOutOfBoundException
    }
}

exception產生時,JVM會由堆疊追蹤此錯誤點的呼叫資訊,並一一向外檢查,直到有try catch區塊攔截此exception為止。在上述的例子中,沒有任何try catch的宣告,則JVM會終止該執行緒

reference :http://blog.csdn.net/kkdelta/article/details/3983318

两篇文章:

http://www.blogjava.net/freeman1984/archive/2007/09/27/148850.html

http://niehan.blog.techweb.com.cn/archives/259.html

六种异常处理的陋习

你觉得自己是一个Java专家吗?是否肯定自己已经全面掌握了Java的异常处理机制?在下面这段代码中,你能够迅速找出异常处理的六个问题吗?

1 OutputStreamWriter out = ...
2 java.sql.Connection conn = ...
3 try { // ⑸
4  Statement stat = conn.createStatement();
5  ResultSet rs = stat.executeQuery(
6   "select uid, name from user");
7  while (rs.next())
8  {
9   out.println("ID:" + rs.getString("uid") // ⑹
10    ",姓名:" + rs.getString("name"));
11  }
12  conn.close(); // ⑶
13  out.close();
14 }
15 catch(Exception ex) // ⑵
16 {
17  ex.printStackTrace(); //⑴,⑷
18 }

  作为一个Java程序员,你至少应该能够找出两个问题。但是,如果你不能找出全部六个问题,请继续阅读本文。

  本文讨论的不是Java异常处理的一般性原则,因为这些原则已经被大多数人熟知。我们要做的是分析各种可称为“反例”(anti-pattern)的违背优秀编码规范的常见坏习惯,帮助读者熟悉这些典型的反面例子,从而能够在实际工作中敏锐地察觉和避免这些问题。

  反例之一:丢弃异常

  代码:15行-18行。

  这段代码捕获了异常却不作任何处理,可以算得上Java编程中的杀手。从问题出现的频繁程度和祸害程度来看,它也许可以和C/C++程序的一个恶名远播的问题相提并论??不检查缓冲区是否已满。如果你看到了这种丢弃(而不是抛出)异常的情况,可以百分之九十九地肯定代码存在问题(在极少数情况下,这段代码有存在的理由,但最好加上完整的注释,以免引起别人误解)。

  这段代码的错误在于,异常(几乎)总是意味着某些事情不对劲了,或者说至少发生了某些不寻常的事情,我们不应该对程序发出的求救信号保持沉默和无动于衷。调用一下printStackTrace算不上“处理异常”。不错,调用printStackTrace对调试程序有帮助,但程序调试阶段结束之后,printStackTrace就不应再在异常处理模块中担负主要责任了。

  丢弃异常的情形非常普遍。打开JDK的ThreadDeath类的文档,可以看到下面这段说明:“特别地,虽然出现ThreadDeath是一种‘正常的情形’,但ThreadDeath类是Error而不是Exception的子类,因为许多应用会捕获所有的Exception然后丢弃它不再理睬。”这段话的意思是,虽然ThreadDeath代表的是一种普通的问题,但鉴于许多应用会试图捕获所有异常然后不予以适当的处理,所以JDK把ThreadDeath定义成了Error的子类,因为Error类代表的是一般的应用不应该去捕获的严重问题。可见,丢弃异常这一坏习惯是如此常见,它甚至已经影响到了Java本身的设计。

  那么,应该怎样改正呢?主要有四个选择:

  1、处理异常。针对该异常采取一些行动,例如修正问题、提醒某个人或进行其他一些处理,要根据具体的情形确定应该采取的动作。再次说明,调用printStackTrace算不上已经“处理好了异常”。

  2、重新抛出异常。处理异常的代码在分析异常之后,认为自己不能处理它,重新抛出异常也不失为一种选择。

  3、把该异常转换成另一种异常。大多数情况下,这是指把一个低级的异常转换成应用级的异常(其含义更容易被用户了解的异常)。

  4、不要捕获异常。

  结论一:既然捕获了异常,就要对它进行适当的处理。不要捕获异常之后又把它丢弃,不予理睬。

  反例之二:不指定具体的异常

  代码:15行。

  许多时候人们会被这样一种“美妙的”想法吸引:用一个catch语句捕获所有的异常。最常见的情形就是使用catch(Exception ex)语句。但实际上,在绝大多数情况下,这种做法不值得提倡。为什么呢?

  要理解其原因,我们必须回顾一下catch语句的用途。catch语句表示我们预期会出现某种异常,而且希望能够处理该异常。异常类的作用就是告诉Java编译器我们想要处理的是哪一种异常。由于绝大多数异常都直接或间接从java.lang.Exception派生,catch(Exception ex)就相当于说我们想要处理几乎所有的异常。

  再来看看前面的代码例子。我们真正想要捕获的异常是什么呢?最明显的一个是SQLException,这是JDBC操作中常见的异常。另一个可能的异常是IOException,因为它要操作OutputStreamWriter。显然,在同一个catch块中处理这两种截然不同的异常是不合适的。如果用两个catch块分别捕获SQLException和IOException就要好多了。这就是说,catch语句应当尽量指定具体的异常类型,而不应该指定涵盖范围太广的Exception类。

  另一方面,除了这两个特定的异常,还有其他许多异常也可能出现。例如,如果由于某种原因,executeQuery返回了null,该怎么办?答案是让它们继续抛出,即不必捕获也不必处理。实际上,我们不能也不应该去捕获可能出现的所有异常,程序的其他地方还有捕获异常的机会??直至最后由JVM处理。

  结论二:在catch语句中尽可能指定具体的异常类型,必要时使用多个catch。不要试图处理所有可能出现的异常。

  反例之三:占用资源不释放

  代码:3行-14行。

  异常改变了程序正常的执行流程。这个道理虽然简单,却常常被人们忽视。如果程序用到了文件、Socket、JDBC连接之类的资源,即使遇到了异常,也要正确释放占用的资源。为此,Java提供了一个简化这类操作的关键词finally。

  finally是样好东西:不管是否出现了异常,Finally保证在try/catch/finally块结束之前,执行清理任务的代码总是有机会执行。遗憾的是有些人却不习惯使用finally。

  当然,编写finally块应当多加小心,特别是要注意在finally块之内抛出的异常??这是执行清理任务的最后机会,尽量不要再有难以处理的错误。

  结论三:保证所有资源都被正确释放。充分运用finally关键词。

反例之四:不说明异常的详细信息

  代码:3行-18行。

  仔细观察这段代码:如果循环内部出现了异常,会发生什么事情?我们可以得到足够的信息判断循环内部出错的原因吗?不能。我们只能知道当前正在处理的类发生了某种错误,但却不能获得任何信息判断导致当前错误的原因。

  printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程,但只提供了一些最基本的信息,未能说明实际导致错误的原因,同时也不易解读。

  因此,在出现异常时,最好能够提供一些文字信息,例如当前正在执行的类、方法和其他状态信息,包括以一种更适合阅读的方式整理和组织printStackTrace提供的信息。

  结论四:在异常处理模块中提供适量的错误原因信息,组织错误信息使其易于理解和阅读。

  反例之五:过于庞大的try块

  代码:3行-14行。

  经常可以看到有人把大量的代码放入单个try块,实际上这不是好习惯。这种现象之所以常见,原因就在于有些人图省事,不愿花时间分析一大块代码中哪几行代码会抛出异常、异常的具体类型是什么。把大量的语句装入单个巨大的try块就象是出门旅游时把所有日常用品塞入一个大箱子,虽然东西是带上了,但要找出来可不容易。

  一些新手常常把大量的代码放入单个try块,然后再在catch语句中声明Exception,而不是分离各个可能出现异常的段落并分别捕获其异常。这种做法为分析程序抛出异常的原因带来了困难,因为一大段代码中有太多的地方可能抛出Exception。

  结论五:尽量减小try块的体积。

  反例之六:输出数据不完整

  代码:7行-11行。

  不完整的数据是Java程序的隐形杀手。仔细观察这段代码,考虑一下如果循环的中间抛出了异常,会发生什么事情。循环的执行当然是要被打断的,其次,catch块会执行??就这些,再也没有其他动作了。已经输出的数据怎么办?使用这些数据的人或设备将收到一份不完整的(因而也是错误的)数据,却得不到任何有关这份数据是否完整的提示。对于有些系统来说,数据不完整可能比系统停止运行带来更大的损失。

  较为理想的处置办法是向输出设备写一些信息,声明数据的不完整性;另一种可能有效的办法是,先缓冲要输出的数据,准备好全部数据之后再一次性输出。

  结论六:全面考虑可能出现的异常以及这些异常对执行流程的影响。

  改写后的代码

  根据上面的讨论,下面给出改写后的代码。也许有人会说它稍微有点?嗦,但是它有了比较完备的异常处理机制。

OutputStreamWriter out = ...
java.sql.Connection conn = ...
try {
 Statement stat = conn.createStatement();
 ResultSet rs = stat.executeQuery(
  "select uid, name from user");
 while (rs.next())
 {
  out.println("ID:" + rs.getString("uid") + ",姓名: " + rs.getString("name"));
 }
}
catch(SQLException sqlex)
{
 out.println("警告:数据不完整");
 throw new ApplicationException("读取数据时出现SQL错误", sqlex);
}
catch(IOException ioex)
{
 throw new ApplicationException("写入数据时出现IO错误", ioex);
}
finally
{
 if (conn != null) {
  try {
   conn.close();
  }
  catch(SQLException sqlex2)
  {
   System.err(this.getClass().getName() + ".mymethod - 不能关闭数据库连接: " + sqlex2.toString());
  }
 }

 if (out != null) {
  try {
   out.close();
  }
  catch(IOException ioex2)
  {
   System.err(this.getClass().getName() + ".mymethod - 不能关闭输出文件" + ioex2.toString());
  }
 }
}

  本文的结论不是放之四海皆准的教条,有时常识和经验才是最好的老师。如果你对自己的做法没有百分之百的信心,务必加上详细、全面的注释。

  另一方面,不要笑话这些错误,不妨问问你自己是否真地彻底摆脱了这些坏习惯。即使最有经验的程序员偶尔也会误入歧途,原因很简单,因为它们确确实实带来了“方便”。所有这些反例都可以看作Java编程世界的恶魔,它们美丽动人,无孔不入,时刻诱惑着你。也许有人会认为这些都属于鸡皮蒜毛的小事,不足挂齿,但请记住:勿以恶小而为之,勿以善小而不为。

====================================================================================================

  本文是Exception处理的一篇不错的文章,从Java Exception的概念介绍起,依次讲解了Exception的类型(Checked/Unchecked),Exception处理的最佳实现:

  1. 选择Checked还是Unchecked的几个经典依据

  2. Exception的封装问题

  3. 如无必要不要创建自己的Exception

  4. 不要用Exception来作流程控制

  5. 不要轻易的忽略捕获的Exception

  6. 不要简单地捕获顶层的Exception

  原文地址:

  http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html

  关于异常处理的一个问题就是要对何时(when)和如何(how)使用它们做到了然于心。在本文中我将介绍一些关于异常处理的最佳实践,同时我也会涉及到最近争论十分激烈的checked Exception的使用问题。

  作为开发员,我们都希望能写出解决问题并且是高质量的代码。不幸的是,一些副作用(side effects)伴随着异常在我们的代码中慢慢滋生。无庸置疑,没有人喜欢副作用(side effects),所以我们很快就用我们自己的方式来避免它,我曾经看到一些聪明的程序员用下面的方式来处理异常:

  public void consumeAndForgetAllExceptions(){

  try {

  …some code that throws exceptions

  } catch (Exception ex){

  ex.printStacktrace();

  }

  }

  上边的代码有什么问题么?

  在回答以前让我们想想怎样才是正确的?是的,一旦程序碰到异常,它就该挂起程序而”做”点什么。那么上边的代码是这样子的么?看吧,它隐瞒了什么?它把所有的”苦水”往肚里咽(在控制台打印出异常信息),然后一切继续,从表面上看就像什么都没有发生过一样……,很显然,上边代码达到的效果并不是我们所期望的。

  后来又怎样?

  public void someMethod() throws Exception{

  }

  上边的代码又有什么问题?

  很明显,上边的方法体是空的,它不实现任何的功能(没有一句代码),试问一个空方法体能抛出什么异常?当然Java并不阻止你这么干。最近,我也遇到类似的情景,方法声明会抛出异常,但是代码中并没有任何”机会”来”展示”异常。当我问开发员为什么要这样做的时候,他回答我说”我知道,它确实有点那个,但我以前就是这么干的并且它确实能为我工作。”

  在C++社区曾经花了数年实践来实践如何使用异常,关于此类的争论在 java社区才刚刚开始。我曾经看到许多Java程序员针对使用异常的问题进行争论。如果对于异常处理不当的话,异常可以大大减慢应用程序的执行速度,因为它将消耗内存和CPU来创建、抛出并捕获异常。如果过分的依赖异常处理,代码对易读和易使用这两方面产生影响,以至于会让我们写出上边两处”糟糕”代码。

  异常原理

  大体上说,有三种不同的”情景”会导致异常的抛出:

  l 编程错误导致异常(Exception due Programming errors): 这种情景下,异常往往处于编程错误(如:NullPointerException 或者 IllegalArgumentException),这时异常一旦抛出,客户端将变得无能为力。

  l 客户端代码错误导致异常(Exception due client code errors): 说白点就是客户端试图调用API不允许的操作。

  l 资源失败导致异常(Exception due to resource failures): 如内存不足或网络连接失败导致出现异常等。这些异常的出现客户端可以采取相应的措施来恢复应用程序的继续运行。

  Java中异常的类型

  Java 中定义了两类异常:

  l Checked exception: 这类异常都是Exception的子类

  l Unchecked exception: 这类异常都是RuntimeException的子类,虽然RuntimeException同样也是Exception的子类,但是它们是特殊的,它们不能通过client code来试图解决,所以称为Unchecked exception

  举个例子,下图为NullPointerException的继承关系:

  图中,NullPointerException继承自RuntimeException,所以它是Unchecked exception.

  以往我都是应用checked exception多于Unchecked exception,最近,在java社区激起了一场关于checked exception和使用它们的价值的争论。这场争论起源于JAVA是第一个拥有Checked exception的主流OO语言这样一个事实,而C++和C#都是根本没有Checked exception,它们所有的异常都是unchecked。

  一个checked exception强迫它的客户端可以抛出并捕获它,一旦客户端不能有效地处理这些被抛出的异常就会给程序的执行带来不期望的负担。

  Checked exception还可能带来封装泄漏,看下面的代码:

  public List getAllAccounts() throws

  FileNotFoundException, SQLException{

  …

  }

  上边的方法抛出两个异常。客户端必须显示的对这两种异常进行捕获和处理即使是在完全不知道这种异常到底是因为文件还是数据库操作引起的情况下。因此,此时的异常处理将导致一种方法和调用之间不合适的耦合。

  接下来我会给出几种设计异常的最佳实践 (Best Practises for Designing the API)

  1. 当要决定是采用checked exception还是Unchecked exception的时候,你要问自己一个问题,”如果这种异常一旦抛出,客户端会做怎样的补救?”

  如果客户端可以通过其他的方法恢复异常,那么这种异常就是checked exception;如果客户端对出现的这种异常无能为力,那么这种异常就是Unchecked exception;从使用上讲,当异常出现的时候要做一些试图恢复它的动作而不要仅仅的打印它的信息,总来的来说,看下表:

  Client’s reaction when exception happens

  Exception type

  Client code cannot do anything

  Make it an unchecked exception

  Client code will take some useful recovery action based on information in exception

  Make it a checked exception

  此外,尽量使用unchecked exception来处理编程错误:因为unchecked exception不用使客户端代码显示的处理它们,它们自己会在出现的地方挂起程序并打印出异常信息。Java API中提供了丰富的unchecked excetpion,譬如:NullPointerException , IllegalArgumentException 和 IllegalStateException等,因此我一般使用这些标准的异常类而不愿亲自创建新的异常类,这样使我的代码易于理解并避免的过多的消耗内存。

  2. 保护封装性(Preserve encapsulation)

  不要让你要抛出的checked exception升级到较高的层次。例如,不要让SQLException延伸到业务层。业务层并不需要(不关心?)SQLException。你有两种方法来解决这种问题:

  l 转变SQLException为另外一个checked exception,如果客户端并不需要恢复这种异常的话;

  l 转变SQLException为一个unchecked exception,如果客户端对这种异常无能为力的话;

  多数情况下,客户端代码都是对SQLException无能为力的,因此你要毫不犹豫的把它转变为一个unchecked exception,看看下边的代码:

  public void dataAccessCode(){

  try{

  ..some code that throws SQLException

  }catch(SQLException ex){

  ex.printStacktrace();

  }

  }

  上边的catch块紧紧打印异常信息而没有任何的直接操作,这是情有可原的,因为对于SQLException你还奢望客户端做些什么呢?(但是显然这种就象什么事情都没发生一样的做法是不可取的)那么有没有另外一种更加可行的方法呢?

  public void dataAccessCode(){

  try{

  ..some code that throws SQLException

  }catch(SQLException ex){

  throw new RuntimeException(ex);

  }

  }

  上边的做法是把SQLException转换为RuntimeException,一旦SQLException被抛出,那么程序将抛出RuntimeException,此时程序被挂起并返回客户端异常信息。

  如果你有足够的信心恢复它当SQLException被抛出的时候,那么你也可以把它转换为一个有意义的checked exception, 但是我发现在大多时候抛出RuntimeException已经足够用了。

  3. 不要创建没有意义的异常(Try not to create new custom exceptions if they do not have useful information for client code.)

  看看下面的代码有什么问题?

  public class DuplicateUsernameException

  extends Exception {}

  它除了有一个”意义明确”的名字以外没有任何有用的信息了。不要忘记Exception跟其他的Java类一样,客户端可以调用其中的方法来得到更多的信息。

  我们可以为其添加一些必要的方法,如下:

  public class DuplicateUsernameException

  extends Exception {

  public DuplicateUsernameException

  (String username){….}

  public String requestedUsername(){…}

  public String[] availableNames(){…}

  }

  在新的代码中有两个有用的方法:reqeuestedUsername(),客户但可以通过它得到请求的名称;availableNames(),客户端可以通过它得到一组有用的usernames。这样客户端在得到其返回的信息来明确自己的操作失败的原因。但是如果你不想添加更多的信息,那么你可以抛出一个标准的Exception:

  throw new Exception(”Username already taken”);

  更甚的情况,如果你认为客户端并不想用过多的操作而仅仅想看到异常信息,你可以抛出一个unchecked exception:

  throw new RuntimeException(”Username already taken”);

  另外,你可以提供一个方法来验证该username是否被占用。

  很有必要再重申一下,checked exception应该让客户端从中得到丰富的信息。要想让你的代码更加易读,请倾向于用unchecked excetpion来处理程序中的错误(Prefer unchecked exceptions for all programmatic errors)。

  4. Document exceptions.

  你可以通过Javadoc’s @throws 标签来说明(document)你的API中要抛出checked exception或者unchecked exception。然而,我更倾向于使用来单元测试来说明(document)异常。不管你采用哪中方式,你要让客户端代码知道你的API中所要抛出的异常。这里有一个用单元测试来测试IndexOutOfBoundsException的例子:

  public void testIndexOutOfBoundsException() {

  ArrayList blankList = new ArrayList();

  try {

  blankList.get(10);

  fail(”Should raise an IndexOutOfBoundsException”);

  } catch (IndexOutOfBoundsException success) {}

  }

  上边的代码在请求blankList.get(10)的时候会抛出IndexOutOfBoundsException,如果没有被抛出,将fail (”Should raise an IndexOutOfBoundsException”)显示说明该测试失败。通过书写测试异常的单元测试,你不但可以看到异常是怎样的工作的,而且你可以让你的代码变得越来越健壮。

  下面作者将介绍界中使用异常的最佳实践(Best Practices for Using Exceptions)

  1. 总是要做一些清理工作(Always clean up after yourself)

  如果你使用一些资源例如数据库连接或者网络连接,请记住要做一些清理工作(如关闭数据库连接或者网络连接),如果你的API抛出Unchecked exception,那么你要用try-finally来做必要的清理工作:

  java 代码

  1. public void dataAccessCode(){

  2. Connection conn = null;

  3. try{

  4. conn = getConnection();

  5. ..some code that throws SQLException

  6. }catch(SQLException ex){

  7. ex.printStacktrace();

  8. } finally{

  9. DBUtil.closeConnection(conn);

  10. }

  11. }

  12.

  13. class DBUtil{

  14. public static void closeConnection

  15. (Connection conn){

  16. try{

  17. conn.close();

  18. } catch(SQLException ex){

  19. logger.error(”Cannot close connection”);

  20. throw new RuntimeException(ex);

  21. }

  22. }

  23. }

  DBUtil是一个工具类来关闭Connection.有必要的说的使用的finally的重要性是不管程序是否碰到异常,它都会被执行。在上边的例子中,finally中关闭连接,如果在关闭连接的时候出现错误就抛出RuntimeException.

  2. 不要使用异常来控制流程(Never use exceptions for flow control)

  下边代码中,MaximumCountReachedException被用于控制流程:

  java 代码

  1. public void useExceptionsForFlowControl() {

  2. try {

  3. while (true) {

  4. increaseCount();

  5. }

  6. } catch (MaximumCountReachedException ex) {

  7. }

  8. //Continue execution

  9. }

  10.

  11. public void increaseCount()

  12. throws MaximumCountReachedException {

  13. if (count >= 5000)

  14. throw new MaximumCountReachedException();

  15. }

  上边的useExceptionsForFlowControl()用一个无限循环来增加count直到抛出异常,这种做法并没有说让代码不易读,但是它是程序执行效率降低。

  记住,只在要会抛出异常的地方进行异常处理。

  3. 不要忽略异常

  当有异常被抛出的时候,如果你不想恢复它,那么你要毫不犹豫的将其转换为unchecked exception,而不是用一个空的catch块或者什么也不做来忽略它,以至于从表面来看象是什么也没有发生一样。

  4. 不要捕获顶层的Exception

  unchecked exception都是RuntimeException的子类,RuntimeException又继承Exception,因此,如果单纯的捕获Exception,那么你同样也捕获了RuntimeException,如下代码:

  try{

  ..

  }catch(Exception ex){

  }

  一旦你写出了上边的代码(注意catch块是空的),它将忽略所有的异常,包括unchecked exception.

  5. Log exceptions just once

  Logging the same exception stack trace more than once can confuse the programmer examining the stack trace about the original source of exception. So just log it once.

2).不同的Exception 要分不同的catch ,做不同的处理

3).先catch子的Exception,再catch父的Exception,否则就子Exception catch 不到

4).自己能处理的Exception才catch ,不能处理的就抛出

5).抛出异常是, 如果期待客户端做具体处理,抛出checked exception,否则抛出unchecked exception。

6).在程序最高层对所有exception做处理,对于runtimeexception,log后继续抛出。

7).不要自己的些没有意义的异常

8).不要写过于庞大的try块

9).是否所有的Exception都要處理?

原則上是的。只要用到的method有宣告throws SomeException,則呼叫該method的地方,就要使用try {} catch(SomeException)的語法。當然像是try {} catch(SuperClassOfSomeException)的用法也行。唯一的例外是java.lang.RuntimeException及其子類別可以不必處理。

哪些屬於RuntimeException呢?像是ArrayIndexOutOfBoundException就是其中之一,它發生在陣列索引不合法的情況下:

public class Test {
    public static void main(String[] argv) {
        int[] x = new int[10];
        x[100] = 0; // will generate ArrayIndexOutOfBoundException
    }
}

exception產生時,JVM會由堆疊追蹤此錯誤點的呼叫資訊,並一一向外檢查,直到有try catch區塊攔截此exception為止。在上述的例子中,沒有任何try catch的宣告,則JVM會終止該執行緒

抱歉!评论已关闭.