在Java中何时使用异常(示例)

在Java中何时使用异常(示例),java,exception,exception-handling,Java,Exception,Exception Handling,我知道这是不好的做法,尽管我知道我无法解释原因 int [] intArr = ... ... try{ int i = 0; while(true){ System.out.println(intArr[i++]); } }catch(ArrayIndexOutOfBoundsException e){} 我认为你只应该对不应该发生的事情使用例外。我问这个问题是因为我认为我有时使用异常是错误的。如果您的程序运行的是标准情况,是否应该抛出异常 这似乎是相关的: 你

我知道这是不好的做法,尽管我知道我无法解释原因

int [] intArr = ...
...
try{
   int i = 0;
   while(true){
      System.out.println(intArr[i++]);
   }
}catch(ArrayIndexOutOfBoundsException e){}
我认为你只应该对不应该发生的事情使用例外。我问这个问题是因为我认为我有时使用异常是错误的。如果您的程序运行的是标准情况,是否应该抛出异常

这似乎是相关的:

你说得对:例外是指,呃,例外情况。使用它们来控制正常的控制流不仅会模糊代码的意图(这已经足以取消它的资格),而且速度要慢得多,因为抛出和捕获异常的成本很高

标准习惯用法(Java5及以上版本)使用foreach循环:


你说得对。异常不应用于处理流程流。

这是错误的,因为您知道循环最终将到达
intArr
的最后一个元素,因此在这方面没有异常,你实际上是在期待这种行为。

你这样吃异常通常被认为是一种不好的做法:如果你不需要做任何进一步的治疗,你可以记录它。

只有在特殊情况下,例如

  • 当一个方法不能做它应该做的事情时
  • 不控制执行流
一如既往地“视情况而定”,你会发现许多不同的意见。这是我的

  • 例外情况分为两大类。
    • 您可以合理预期和处理的事情(FileNotFoundException)
    • 假设代码完美(ArrayIndexOutOfBounds),您通常不会复制的内容
您通常希望处理第一类,而不是后一类。后者通常是编程错误

您的示例属于后一种情况,即编程错误。异常旨在在运行时提供有关故障的良好信息,而不是作为控制流


有些人会说,第一个是检查异常,第二个是未检查异常。我不同意这一点。我几乎总是发现检查异常在现实中是一件痛苦的事情,因为您几乎总是要对另一种异常类型执行catch/wrap/rethrow。在抛出异常和定义自己的异常类时,我几乎总是使用unchecked。

异常应该捕获异常,记录它,并在可能的情况下进行恢复

如果它是正常程序流的一部分,您应该正常处理它。

异常用于代码中的异常。不适用于标准案例

但是,您的代码还有一个更严重的问题,如果不使用exception,它的速度会更慢。创建异常、抛出异常和捕获异常需要额外的CPU和内存


另外,对于那些只希望在错误情况下抛出异常的程序员来说,代码也变得更难阅读。

捕获异常只是在涉及错误时的一种不好的做法。您试图捕捉的
ArrayIndexOutOfBoundsException
存在一个异常

运行时异常
识别由代码流中的错误引起的可编程恢复的问题。您不应该通过捕获它们来修复它们,而应该编写适当的代码并使用流控制语句,如
if/else
while
for
,等等

另见:

到达阵列末端并非例外情况。在开始循环之前,您知道长度,所以只需使用标准的习惯用法即可

for(int i = 0; i < intArr.length; ++i) {
    System.out.println(intArr[i]);
} 
for(int i=0;i
+1这就是为什么不应该使用Integer.Parse,如果您知道它会定期失败。Ex解析多个可能失败的xxxxxx编号。相反,您将在C#(java等效)中使用类似int.TryParse的东西。不抛出异常时,异常速度很快。但是当它们被抛出时,它们的速度相当慢(创建带有消息的新对象,进行大量嵌套捕获等)。@Lassee虽然我同意你的逻辑,但我不相信有一种java等价物可以与tryparseh媲美。你读过Joshua Bloch的《高效java》吗?他有一个与您非常相似的代码示例,并且对为什么不这样做有很好的解释。我强烈建议你阅读那本书的例外章节。
for(int i = 0; i < intArr.length; ++i) {
    System.out.println(intArr[i]);
}