Java:捕获的含义(最终的SomeException e)?

2022-09-01 01:33:51

在下面的 Java 表达式中有什么作用?final

catch (final SomeExceptionType e)

答案 1

它基本上意味着:

将“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;
}

通常被认为是线程安全的,因为它这样做(在伪字节码中)

(In the thread's current frame)
push 5
push 5
add integers
return

虽然这不是线程安全的

int x = 5;

public void unsafe() {
  x = 5;
  x = x + 5;
  return x;
}

因为它这样做

(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

后一个字节码清楚地表明,交错两个线程使用成员x作为中介创建线程到线程的通信,而第一个代码块不能有任何线程间通信,因为没有中介。


答案 2

目前,它的含义与任何局部变量大致相同,只是它总是“明确分配”。final

在最近的JDK7版本中,Project Coin语言的更改允许它表明一定程度的隐式静态类型正在进行中。单个可以通过一个通用的基类型捕获许多不同的已检查异常,并且重新调用仅具有捕获或声明那些可以(静态地)在 .(有关更好的解释,请参阅链接。catchtry


推荐