代码之家  ›  专栏  ›  技术社区  ›  Joel

Java异常处理风格

  •  10
  • Joel  · 技术社区  · 16 年前

    历史上,我总是这样编写异常处理代码:

        Cursor cursor = null;
        try {
            cursor = db.openCursor(null, null);
            // do stuff
        } finally {
            if (cursor != null) cursor.close();
        }
    

            Cursor cursor = db.openCursor(null, null);
            try {           
                // do stuff
            } finally {
                cursor.close();
            }
    

    除非JVM在赋值时实际爆炸,或者在赋值和try块中的第一行之间爆炸,否则我不确定我的旧样式是否有任何额外的价值,第二行肯定更具可读性和简洁性。文学 generally

    编辑 -假设我很高兴openCursor在初始化游标时抛出的任何异常不会在这段代码中被捕获,我对这个示例唯一关心的是关闭游标 分配及;开的。阿尔索 假设我正在测试空值 等等雅达。。。雅达(我改变了示例以反映这一点,它不是我问题的焦点,因此我没有将其包含在第一个版本中)

    8 回复  |  直到 16 年前
        1
  •  6
  •   PSpeed    16 年前

    如果您在finally中所做的只是关闭光标,那么第二种形式是正确的。你会

    正如其他人所提到的,警告是,如果您正在进行需要自己清理的额外初始化,那么在逻辑上必须进入finally{},并相应地更改范围。尽管我认为在这种情况下应该进行重组。

    底线:正如所写的,第一个版本是不必要的复杂。第二个版本是正确的。

    编辑:为后代加入我的其他评论。。。

    因此,我愿意称第一个例子为“完全错误”。我当然会在代码审查中标记它。

        2
  •  13
  •   jdmichal    16 年前

    我总是用第二种方法来做,因为它允许我将光标设置为 final . 如果您实际上没有试图从try子句捕获异常,那么我看不出有任何理由在try子句中包含赋值。

    编辑:只是要注意,从进一步的讨论已经进行。这就是我处理这个问题的方式 openCursor 引发异常的调用:

    try
    {
        // ALLOCATE RESOURCE
        final Cursor cursor = db.openCursor(null, null);
    
        try
        {
            // USE RESOURCE
        }
        finally
        {
            // DISPOSE RESOURCE
            cursor.close();
        }
    }
    catch(OpenCursorException e)
    {
        // Handle this appropriately.
    }
    

    try 块抛出与分配捕获的异常相同的异常 街区( IOException 这将是一个特别好的例子,因为打开和读取都会抛出一个。)在这种情况下,所有内容仍将正确清理和处置,但您可能会错误地将失败归因于初始化异常,而不是使用异常。在这种情况下,您将希望捕获内部 立即在那里堵住并处理它们。

        3
  •  11
  •   Mark Byers    16 年前

    (更新:该问题已根据此答案更正,因此此答案的第一部分不再有意义。)

    第一个例子是错误的。如果db.openCursor失败,它将抛出NullPointerException。第二个更好。

    Cursor cursor = null;
    try {
        cursor = db.openCursor(null, null);
        // do stuff
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    

    不过,用第二种方法做这件事并不比用第二种方法更安全,但它经常在示例中使用,而且我在实际代码中也看到了大量使用。

    第二种方法更好的一个原因是 // do stuff 节可以将光标设置为null,从而导致光标未关闭并造成泄漏。总而言之,我看不到使用第一个方法的好理由(即使使用空检查更正了它),也看不到避免使用它的理由。坚持第二种方法。

        4
  •  6
  •   erickson    16 年前

    null ,在本例中)以抑制有关使用未初始化变量的编译器警告。相反,请注意警告,并按照第二个“懒惰”示例所示正确初始化变量。

        5
  •  1
  •   fastcodejava    16 年前

    这样做真的没有错:

    Cursor cursor = db.openCursor(null, null);  
      try {  
         // do stuff  
       } finally {  
          try {  
            cursor.close();  
         } catch( SomeOther so ){}  
     }  
    
        6
  •  0
  •   user12786    16 年前

    如果openCursor()方法没有抛出异常,则后者也可以。如果是的话,那么你肯定会想用前者。原因是任何异常都会被抛出给调用方。如果调用方法未设置为处理该问题,则存在问题。

        7
  •  0
  •   ChssPly76    16 年前

    第二种风格很好 只要 这两个方法参数都不是可以引发自身异常的计算表达式,需要在之后进行清理。

        8
  •  0
  •   hari    15 年前

    不同的人有不同的意见。但建议使用第一种选择,因为如果打开光标时出现任何问题,可能会抛出异常并进行处理。这是一种安全的编程方法。