try {
throw new Exception();
catch (Exception e){
e = null;
e.printStackTrace(); //throws a NullPointerException
}
这个问题在这个简单的例子中很明显,但是有两种情况可能不那么明显,需要使用final: 1.如果catch块更复杂,则可能会发生意外的重新分配(尽管如此,如果catch块很复杂,则可能会做错)。 1.防止代码维护期间出现问题。将final添加到异常变量将确保在编译时捕获重新分配,* 而不是在运行时捕获 * 作为一般经验法则,请在 *uni-catch子句 * in the same way you would use the final keyword for a method parameter中使用final关键字: 日本劳工标准§4.12.4:将变量声明为final可以作为有用的文档,说明其值不会更改,并有助于避免编程错误。
4条答案
按热度按时间6yt4nkrj1#
它的基本意思是:
将"SomeExceptionType"捕获到变量"e"中,并承诺在处理异常期间不会将不同的异常赋给"e"。
大多数情况下,这是矫枉过正的,就好像我在一个临时变量名中捕捉一个异常(e只对异常处理块有效),我不必如此严格地约束自己,以至于不相信自己会给同一个变量名分配一个不同的(可能是创建的)异常。
也就是说,也许这个块是由一个想法不同的人组成的团队大量维护的,人们只是想非常确定e是最初捕获的异常。
我想不出一个很好的理由。因为"e"不是会员(静态或其他)名称"e"将不会被类文件编译后使用。另一种说法是,当您进入JVM字节码的异常处理块时,对象不会被分配给JVM处理框架可访问的任何成员名称,它将被推送到Thread当前帧的内部处理堆栈。
即使两个线程访问同一个Object,每个线程都有自己的帧,因此编译器从一个帧的内部堆栈中删除"e"名称时,另一个线程无法更改它。
考虑到这一点,声明"e" final的唯一好处是确保未来的程序员在进入块后不会意外地设置"e"。也许他们是想让代码在多线程环境中更健壮,但临时变量(那些名称仅在块中有效的变量)在编译后没有名称,它们被推送到帧的堆栈中。
这就是为什么
通常被认为是线程安全的,因为它这样做(在伪字节码中)
虽然这不是线程安全的
因为它会这样
后一个字节码清楚地表明,交错两个线程使用成员x作为中介创建了线程到线程的通信,而第一个代码块不能进行任何线程间通信,因为没有中介。
kb5ga3dv2#
目前,它的含义与任何局部变量
final
几乎相同,只是它总是“明确赋值”。在最近的JDK7构建中,a Project Coin language change允许它指示某种程度的隐式静态类型正在进行。单个
catch
可以通过一个公共基类捕获许多不同的检查异常,并使用仅捕获或声明那些可能(静态地说)在try
中抛出的异常的封闭上下文重新抛出。(参见链接以获得更好的解释。)pgccezyw3#
这个问题,“
final
做什么?”在这个问题的其他答案中,以及here,here,和here中都有提到,但是在 try-catch 块的上下文中,Java语言规范(JLS)§4.12.4规定(强调我自己):*try-with-resources语句(参见14.20.3节)的资源和multi-catch子句(参见14.20节)的异常参数都被隐式声明为final。
uni-catch子句(§14.20)的异常参数可以是final的,而不是显式声明为final的,这样的参数 * 从不隐式声明为final。
在多catch子句中:
将
final
关键字添加到一个 *multi-catch子句 * 中,只会显式地表明variable
是隐式final的事实。通常,只要final
关键字传达了有助于提高代码可读性/可维护性的附加信息,就可以使用它。在单向捕获子句中
另一方面,*uni-catch子句 * 中的exception参数是never隐式final。因此,在 *uni-catch子句 * 中使用
final
关键字可以防止以下情况发生:这个问题在这个简单的例子中很明显,但是有两种情况可能不那么明显,需要使用
final
:1.如果catch块更复杂,则可能会发生意外的重新分配(尽管如此,如果catch块很复杂,则可能会做错)。
1.防止代码维护期间出现问题。将
final
添加到异常变量将确保在编译时捕获重新分配,* 而不是在运行时捕获 *作为一般经验法则,请在 *uni-catch子句 * in the same way you would use the
final
keyword for a method parameter中使用final
关键字:日本劳工标准§4.12.4:将变量声明为final可以作为有用的文档,说明其值不会更改,并有助于避免编程错误。
2ul0zpep4#
变量上的
final
关键字意味着变量只能被赋值一次,由于这里的赋值是由编译器完成的,这意味着变量不能在代码中稍后更改。这是一个重要的属性,因为它意味着对于维护者来说,这个特定的变量在任何地方使用时都将具有这个特定的值,并且没有必要跟踪它在哪里更改。这被认为是非常有用的,以至于Eclipse中的“清理”操作允许在任何可能的地方添加“final”,并且我相信您所看到的是这样一个自动清理的 * 结果 *。因为大多数人类程序员将保持捕捉块较短,因此不需要这样的指示。