Pla*_*mer 32 java final exception-handling exception
是什么final在以下Java表达式吗?
catch (final SomeExceptionType e)
Run Code Online (Sandbox Code Playgroud)
Edw*_*uck 32
它基本上意味着:
将"SomeExceptionType"捕获到变量"e"中,并保证在处理异常期间我们不会为"e"分配不同的异常.
大多数情况下这都是矫枉过正,好像我正在将一个异常捕获到一个临时变量名中(e只对异常处理块有效),我不必严格警告自己,不要相信自己指定一个不同的(可能已创建)相同变量名的异常.
也就是说,也许这个区块由一群心胸不同的人大量维护,而且只是想要非常确定e是原始捕获的异常.
----编辑回应评论----
我无法想到这样做的一个非常好的理由.由于"e"不是成员(静态或其他),因此编译后的类文件不会使用名称"e".说明这一点的另一种方法是,当您输入JVM字节码的异常处理块时,该对象将不会被分配给JVM处理框架可访问的任何成员名称,它将被推送到Thread的内部处理堆栈中.当前帧.
即使两个线程可以访问同一个Object,每个线程都有自己的帧,因此编译器从一个帧的内部堆栈中删除"e"名称不能被另一个线程更改.
考虑到这一点,宣布"e"final的唯一好处是确保未来的编码人员在进入区块后不会意外设置"e".也许它们意味着在多线程环境中使代码更加健壮,但临时变量(名称仅在块中有效的那些变量)在编译后没有名称,它们被推送到帧的堆栈中.
这就是为什么
public int safe() {
int x = 5;
x = x + 5;
return x;
}
Run Code Online (Sandbox Code Playgroud)
通常被认为是线程安全的,因为它这样做(伪字节码)
(In the thread's current frame)
push 5
push 5
add integers
return
Run Code Online (Sandbox Code Playgroud)
虽然这不是线程安全的
int x = 5;
public void unsafe() {
x = 5;
x = x + 5;
return x;
}
Run Code Online (Sandbox Code Playgroud)
因为它做到了这一点
(in the thread's current frame)
push "this"
push 5
set member x
push "this"
get member x
push 5
add integer
set member x
get member x
return
Run Code Online (Sandbox Code Playgroud)
后一个字节码显然交错两个线程使用成员x和中间件创建线程到线程的通信,而第一个代码块不能有任何线程间通信,因为没有中间件.
Tom*_*ine 11
目前它意味着final与任何局部变量大致相同,除了它总是"明确分配".
在最近的JDK7版本中,Project Coin语言更改允许它指示一定程度的隐式静态类型正在进行.单个catch可以通过公共基类型捕获许多不同的已检查异常,并且重新抛出包含上下文仅具有catch或声明可以(静态地说)被抛出的异常try.(有关更好的解释,请参阅链接.)
问题是“做final什么?” 在这个问题的其他答案中,在这里,在这里和在这里都得到解决。但是在try-catch块的上下文中,Java语言规范(JLS)§4.12.4声明(强调我自己):
- 一个的资源的尝试,与资源的语句(§14.20.3)和一个异常参数多catch子句(§14.20)被隐式声明为final。
- uni-catch子句的异常参数(第 14.20节)可以有效地是final,而不是被明确声明为final。此类参数永远不会隐式声明为final。
在多捕获子句中:
将final关键字添加到multi-catch子句中只会使variable隐式最终的事实变得明确。通常,每当final关键字传达有助于使您的代码更具可读性/可维护性的其他信息时,请使用它。
在单捕获子句中
在另一方面,在异常参数UNI-catch子句是永远隐含决赛。因此,final对uni-catch子句使用关键字可以防止发生以下情况:
try {
throw new Exception();
catch (Exception e){
e = null;
e.printStackTrace(); //throws a NullPointerException
}
Run Code Online (Sandbox Code Playgroud)
在这个简单的示例中,问题很明显。但是有两种情况可能不太明显,因此可以使用final:
final到异常变量将确保在编译而不是运行时捕获重新分配根据经验,final在uni-catch子句 中使用final关键字的方式与在方法参数中使用关键字的方式相同:
JLS§4.12.4:声明变量final可作为有用的文档,说明其值不会更改,并有助于避免编程错误。
| 归档时间: |
|
| 查看次数: |
15370 次 |
| 最近记录: |