在捕获异常时是否有理由不使用final关键字?

时间:2012-08-21 09:19:47

标签: java performance exception final

我在一些示例BlackBerry Java类中看到了一些代码:

try
{
    // stuff that will throw an exception
}
catch(final Exception e)
{
    // deal with it
}

我认为final是为了表现。根据标题,因为很少(永远?)任何理由修改已被抛出的Exception,它们应该始终是final吗?

如果是这样,这不是编译器可以完成的事情吗?或者它是由编译器完成的,手动添加final根本没有影响吗?

5 个答案:

答案 0 :(得分:17)

The Java Language Specification 11.2.2在最终例外与非最终例外之间有所区别:

  

throw语句(第14.18节),其抛出的表达式具有静态类型E,并且不是最终或有效的最终异常参数,可以抛出E或抛出的表达式可以抛出的任何异常类。
  [...]
  抛出语句表达式是catch子句C的最终或有效最终异常参数的throw语句可以抛出异常类E iff:

     
      
  • E是一个异常类,声明C的try语句的try块可以抛出;和
  •   
  • E的赋值与C的任何可捕获异常类兼容;和
  •   
  • E与赋值在同一个try语句中的C左侧的catch子句的任何可捕获异常类不兼容。
  •   

有趣的是,JLS 14.20也说:

  

在uni-catch子句中,如果一个未声明为final(隐式或显式)的异常参数在其作用域内从不作为赋值运算符的左侧操作数发生,则它被认为是有效的。

换句话说,如果您不重新分配catch语句的e(如e = new SomeOtherException();),则会隐式声明为final。

所以我只能得出结论,它没有什么区别,除非在catch块中修改了异常,我能想出的唯一例子是:

public void method1() throws IOException {
    try {
        throw new IOException();
    } catch (Exception e) { // e is not modified in catch => implicitly final
        throw e; //compiles OK
    }
}

//it works because method1 is semantically equivalent to method2:
public void method2() throws IOException {
    try {
        throw new IOException();
    } catch (final Exception e) {
        throw e;
    }
}

public void method3() throws IOException {
    try {
        throw new IOException("1");
    } catch (Exception e) {
        e = new IOException("2"); //e modified: not implicitly final any more
        throw e; //does not compile
    }
}

答案 1 :(得分:2)

我相信final在可能使用它的代码太长而无法轻松阅读和理解时非常有用。例如我会在可能的情况下创建字段final,以确保它们在构造函数中正确分配,而不是在类中的任何位置进行修改。

final用于catch子句不太可能有用,因为a)保证设置值b)使用它的代码应该很短,c)无论如何很难修改它。

然而,没有什么可以阻止你这样做。

答案 2 :(得分:0)

我不确定它是关于性能的,而是关于约定的更多信息。如果您正在使用Eclipse,请尝试设置一个格式化程序,在任何可能的地方添加final关键字,并使用该格式化程序重新格式化您的源代码。

答案 3 :(得分:-1)

我怀疑final会真正给出任何性能上的好处,因为异常实例是block local(这是一个非常好的答案,解释它https://stackoverflow.com/a/306966/492561)。

所以它只是作为一个明确的标记,表示我不会修改。

有时您可能需要修改异常以将其丢回,可能会编辑消息以使其在更高级别更清晰。

基本上我会说这是一个偏好的问题,有些人可能会喜欢其他人可能没有。

答案 4 :(得分:-1)

我见过几个项目,其中未修改的所有内容都必须是最终的(例如参数,字段,本地变量等)。

PMD代码分析器中还有一个相应的样式检查,它验证所有可能的内容都被声明为final