Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java:catch(最后的somee)的含义?_Java_Exception_Exception Handling_Final - Fatal编程技术网

Java:catch(最后的somee)的含义?

Java:catch(最后的somee)的含义?,java,exception,exception-handling,final,Java,Exception,Exception Handling,Final,final在下面的Java表达式中做什么 catch (final SomeExceptionType e) 它基本上意味着: 将“SomeExceptionType”捕获到变量“e”中,并承诺在异常处理过程中不会将不同的异常分配给“e” 大多数情况下,这是过分的,就像我正在将异常捕获到一个临时变量名中一样(e仅对异常处理块有效),我不必严格控制自己,以至于不相信自己会将不同的(可能创建的)异常分配给同一个变量名 这就是说,也许这个区块主要由一个由不同想法的个人组成的团队维护,人们只是想非常确

final
在下面的Java表达式中做什么

catch (final SomeExceptionType e)
它基本上意味着:

将“SomeExceptionType”捕获到变量“e”中,并承诺在异常处理过程中不会将不同的异常分配给“e”

大多数情况下,这是过分的,就像我正在将异常捕获到一个临时变量名中一样(e仅对异常处理块有效),我不必严格控制自己,以至于不相信自己会将不同的(可能创建的)异常分配给同一个变量名

这就是说,也许这个区块主要由一个由不同想法的个人组成的团队维护,人们只是想非常确定e是最初捕获的例外

----根据评注编辑----

我想不出有什么好的理由这么做。由于“e”不是成员(静态或其他),编译后类文件不会使用名称“e”。另一种方式是,当您输入JVM字节码的异常处理块时,对象不会被分配给JVM处理框架可以访问的任何成员名称,它将被推送到线程当前框架的内部处理堆栈

即使两个线程可以访问同一个对象,每个线程都有自己的框架,因此编译器从一个框架的内部堆栈中删除了“e”名称,而另一个线程则无法更改

考虑到这一点,声明“e”final的唯一好处是确保未来的编码人员不会在进入块后意外设置“e”。也许它们的目的是使代码在多线程环境中更加健壮,但是临时变量(那些名称仅在块中有效的变量)在编译后没有名称,它们被推到框架堆栈上

这就是为什么

public int safe() {
  int x = 5;
  x = x + 5;
  return x;
}
通常被认为是线程安全的,因为它做到了这一点(在伪字节码中)

虽然这不是线程安全的

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构建中,允许它指示某种程度的隐式静态类型正在进行。单个
catch
可以通过一个公共基类型捕获许多不同的已检查异常,并在封闭上下文中仅具有catch或声明那些可以(静态地说)在
try
中抛出的异常的情况下重试。(请参阅链接以获得更好的解释。)

变量上的
final
关键字意味着变量只能赋值一次,并且由于此处的赋值是由编译器完成的,因此意味着变量不能在以后的代码中更改

这是一个重要的属性,因为它对维护人员意味着这个特定变量在使用它的任何地方都会有这个特定的值,并且没有必要跟踪它在哪里变化。这被认为是非常有用的,因此Eclipse中的“清理”操作允许在任何可能的地方添加“final”,我相信您看到的是这种自动清理的结果,因为大多数人类程序员都会保持catch块简短,因此不需要这样的指示。

问题是,“final做什么?”在这个问题的其他答案中提到,和。但是在try-catch块的上下文中,强调(我自己):

  • try with resources语句的资源(§14.20.3)和多捕获子句(§14.20)的异常参数隐式声明为final
  • uni catch子句(§14.20)的异常参数可以是有效的final,而不是显式声明为final。此类参数从不隐式声明为final
在多捕获子句中

final
关键字添加到multi-catch子句中,只需明确说明
变量
是隐式final。通常,只要
final
关键字传递了有助于使代码更具可读性/可维护性的附加信息,就可以使用它

在单捕获子句中

另一方面,uni-catch子句中的异常参数是从不隐式final。因此,对uni-catch子句使用
final
关键字可防止发生以下情况:

try {
     throw new Exception();
catch (Exception e){
    e = null;
    e.printStackTrace(); //throws a NullPointerException
}
在这个简单的例子中,这个问题是显而易见的。但有两种情况可能不那么明显,需要使用
final

  • 如果catch块更复杂,则可能会发生意外的重新分配(不过,如果catch块复杂,则可能是做错了)
  • 防止在代码维护期间出现问题。将
    final
    添加到异常变量将确保在编译时而不是运行时捕获重新分配
  • 一般来说,在uni catch子句中使用
    final
    关键字:

    :声明变量final可以作为有用的文档,它的值不会更改,并有助于避免编程错误


    这种情况什么时候会发生?我猜是在多线程环境中,但你能用一个小例子来说明吗?@nightone:Multi-threading与此无关。由于变量“e”是处理程序块的本地变量,因此无法从其他线程访问它。我认为如果你有一个长而复杂的handler block-但在这种情况下,你可能还是做错了。@noctune:通过标记“e”final,作者禁止“e”被再次使用
    try {
         throw new Exception();
    catch (Exception e){
        e = null;
        e.printStackTrace(); //throws a NullPointerException
    }