final
在下面的 Java 表达式中做了什么?
catch (final SomeExceptionType e)
最佳答案
基本意思是:
将“SomeExceptionType”捕获到变量“e”中,并 promise 在处理异常期间我们不会为“e”分配不同的异常。
大多数情况下这是矫枉过正,就好像我正在将异常捕获到临时变量名中(e 仅对异常处理 block 有效),我不必如此严格地监管自己,以免自己不相信自己分配同一变量名的不同(可能已创建)异常。
也就是说,也许这个 block 是由一群志同道合的人大量维护的,一个人只是想非常确定 e 是最初捕获的异常。
----根据评论编辑----
我想不出一个非常好的理由来做这件事。由于“e”不是成员(静态或其他),因此类文件编译后不会使用名称“e”。另一种说法是,当你进入 JVM 字节码的异常处理 block 时,该对象不会被分配给 JVM 处理框架可访问的任何成员名称,它会被推送到 Thread 的内部处理堆栈中。当前帧。
即使两个线程可以访问同一个对象,每个线程也会有自己的框架,因此编译器从一个框架的内部堆栈中删除了“e”名称,其他线程无法更改。
考虑到这一点,声明“e”final 的唯一好处是确保 future 的编码人员不会在进入 block 后意外设置“e”。也许他们的目的是让代码在多线程环境中更加健壮,但是临时变量(名称仅在 block 中有效的变量)在编译后没有名称,它们被推送到帧的堆栈中。
这就是为什么
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 作为中介创建线程间通信,而第一个代码块不能进行任何线程间通信,因为没有中介。
关于Java:catch 的含义(final SomeException e)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3516816/