有没有理由在捕获异常时不使用final关键字? [英] Is there ever a reason to not use the final keyword when catching an exception?

查看:84
本文介绍了有没有理由在捕获异常时不使用final关键字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一些例子中看到一些代码如BlackBerry Java类:

  try 
{
//将抛出异常的东西
}
catch(final Exception e)
{
//处理
}

我假定 final 是为了表演。根据标题,由于很少(永远?)有任何理由修改已被抛出的异常,如果它们总是 final



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

解决方案

Java语言规范11.2.2 在最终和非最终的例外之间有所区别:


一个throw语句(§14.18)抛出的表达式具有静态类型E,并且不是最终或有效的最终异常参数可以抛出E或抛出的表达式可以抛出的任何异常类。

[...]

A throw语句的抛出表达式是catch子句的最终或有效的最终异常参数C可以抛出异常类E iff:




  • E是一个异常类,即try语句的try块可以抛出;和

  • E是与C的任何可捕获的异常类兼容的转移;和

  • E不与任何在同一个try语句中声明为C左边的catch子句的可捕获的异常类分配兼容。

  • <有意思的是, 14.html#jls-14.20-620rel =noreferrer> 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在catch =>中未修改隐含最终
    throw e; //编译OK
    }
    }

    //它的工作原理是因为method1在语义上等同于method2:
    public void method2()throws IOException {
    尝试{
    抛出新的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
    throw e; //不编译
    }
    }


    I've seen some code as below in some example BlackBerry Java classes:

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

    I presume the final is for performance. As per the title, since there's rarely (ever?) any reason to modify an Exception that's already been thrown, should they always be final?

    If so, isn't this something that could be done by the compiler? Or is it done by the compiler and adding the final manually has no impact at all?

    解决方案

    The Java Language Specification 11.2.2 makes a difference between final and not final exceptions:

    A throw statement (§14.18) whose thrown expression has static type E and is not a final or effectively final exception parameter can throw E or any exception class that the thrown expression can throw.
    [...]
    A throw statement whose thrown expression is a final or effectively final exception parameter of a catch clause C can throw an exception class E iff:

    • E is an exception class that the try block of the try statement which declares C can throw; and
    • E is assignment compatible with any of C's catchable exception classes; and
    • E is not assignment compatible with any of the catchable exception classes of the catch clauses declared to the left of C in the same try statement.

    Interestingly, JLS 14.20 also says:

    In a uni-catch clause, an exception parameter that is not declared final (implicitly or explicitly) is considered effectively final if it never occurs within its scope as the left-hand operand of an assignment operator.

    In other words, if you don't reassign the e of your catch statement (like e = new SomeOtherException();), it is implicitly declared final.

    So I can only conclude that it does not make a difference, unless the exception is modified in the catch block and the only example I can come up with is:

    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
        }
    }
    

    这篇关于有没有理由在捕获异常时不使用final关键字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆