在以下Java表达式中,final
是什么作用?
catch (final SomeExceptionType 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作为中介进行线程与线程之间的通信,而第一个代码块没有任何线程间通信,因为没有中介。
目前它意味着final
与任何局部变量基本相同,除了它始终"已定义"。
在最近的JDK7构建中,一个Project Coin语言更改允许它指示正在进行一定程度的隐式静态类型。单个catch
可以通过共同的基础类型捕获多种不同的已检查异常,并在尝试内(从静态角度)可能抛出这些异常的情况下,使用包含上下文重新抛出或声明这些异常。 (请参阅链接以获得更好的解释。)
final
是什么?”的问题。但在 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。
在 multi-catch 子句中:
将 final
关键字添加到 multi-catch 子句 中只是明确了该 variable
隐式地被声明为 final。通常情况下,只要 final
关键字传达了有助于使代码更易读/易维护的其他信息,就应该使用它。
在 uni-catch 子句中
另一方面,在 uni-catch 子句 中,异常参数从不会被隐式地声明为 final。因此,在 uni-catch 子句 中使用 final
关键字可以防止出现以下情况:
try {
throw new Exception();
catch (Exception e){
e = null;
e.printStackTrace(); //throws a NullPointerException
}
final
来解决:
final
添加到异常变量中,将确保在编译时捕获重新分配,而不是在运行时捕获。final
关键字,就像使用方法参数的final
关键字一样:
JLS§4.12.4 : 声明一个变量为final可以作为有用的文档,说明它的值不会改变,并有助于避免编程错误。
final
关键字意味着该变量只能被赋值一次,由于此处的赋值是由编译器执行的,因此在代码后期无法更改该变量的值。
这是一个重要的属性,因为它意味着对于维护者来说,该特定变量在使用时将具有特定的值,并且不需要跟踪其更改的位置。这被认为非常有用,以至于Eclipse中的“清理”操作允许在可能的情况下添加“final”,我相信您看到的是这种自动清理的结果,因为大多数人类程序员会保持catch-block简短,因此不需要这样的指示。