Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.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中检查错误值或捕获异常_Java_Performance_Exception_Optimization_Error Handling - Fatal编程技术网

哪一个更好/更有效:在Java中检查错误值或捕获异常

哪一个更好/更有效:在Java中检查错误值或捕获异常,java,performance,exception,optimization,error-handling,Java,Performance,Exception,Optimization,Error Handling,在Java中,哪个更有效:检查错误值以防止异常,还是让异常发生并捕获它们 下面是两段示例代码来说明这种差异: void doSomething(type value1) { ResultType result = genericError; if (value1 == badvalue || value1 == badvalue2 || ...) { result = specificError; } else { DoSom

在Java中,哪个更有效:检查错误值以防止异常,还是让异常发生并捕获它们

下面是两段示例代码来说明这种差异:

void doSomething(type value1) {
    ResultType result = genericError;

     if (value1 == badvalue || value1 == badvalue2 || ...) {
          result = specificError;
     } else {
          DoSomeActionThatFailsIfValue1IsBad(value1);
          // ...
          result = success;
     }
     callback(result);
}

void doSomething(type value1) {
     ResultType result = genericError;
     try {
          DoSomeActionThatFailsIfValue1IsBad(value1);
          // ...
          result = success;
     } catch (ExceptionType e) {
          result = specificError;
     } finally {
          callback(result);
     }
}
一方面,你总是在做比较。另一方面,我真的不知道系统的内部如何生成异常,抛出异常,然后触发catch子句。它听起来效率较低,但如果在无错误的情况下不增加开销,那么平均而言,它的效率会更高。是哪一个?它是否添加了类似的检查?是否在隐式代码中添加了异常处理的检查,即使有额外的显式检查层?也许它总是取决于异常的类型?我没有考虑什么

让我们假设所有的“坏值”都是已知的——这是一个明显的问题。如果您不知道所有的错误值,或者列表太长且不规则,那么无论如何,异常处理可能是唯一的方法

那么,每种方法的优缺点是什么,为什么

要考虑的附带问题:

  • 如果值在大多数情况下为“坏”(将引发异常),您的答案会如何变化
  • 这在多大程度上取决于正在使用的虚拟机的具体情况
  • 如果对language-X提出同样的问题,答案会不同吗?(更一般地说,这是在询问是否可以假设检查值总是比依赖异常处理更有效,因为这会增加当前编译器/解释器的开销。)
  • (新)抛出异常的行为是缓慢的。即使没有抛出异常,输入try块也会有开销吗

因此:

  • 这与中的代码示例相似,但说明它们仅在概念上相似,而不是在实际编译中
  • 前提类似于,但在我的例子中,任务的请求者(例如“某物”)不是方法的调用方(例如“doSomething”)(因此没有返回)
  • 非常相似,但我没有找到我问题的答案

  • 与太多其他问题类似,除了:

    我不是在问理论上的最佳实践。我想了解更多关于运行时性能和效率的信息(这意味着,对于特定情况,会有非意见的答案),特别是在资源有限的平台上。例如,如果唯一的坏值只是一个空对象,那么检查它是否更好/更有效,或者只是尝试使用它并捕获异常


在我看来,您应该在任何可能引发异常的东西周围设置try/catch块,只要有一个安全运行的系统。如果首先检查可能的数据错误,则可以更好地控制错误响应。所以我建议两者都做。

如果值在大多数情况下是“坏”(会引发异常)的,那么答案会如何变化?我认为这是关键所在。与比较相比,异常是昂贵的,因此您确实希望在异常条件下使用异常


类似地,您关于这个答案可能会随着语言/环境的变化而变化的问题与此相关:在不同的环境中,异常的代价是不同的。例如,Net 1.1和2.0在第一次抛出异常时速度非常慢。

我个人的观点是,异常表明某些东西被破坏了-这很可能是一个使用非法参数调用的API,或者被零除或找不到文件等。这意味着可以通过检查值来抛出异常

对于代码的读者来说——同样是我个人的观点——如果你能确定它不会被各种奇怪的抛出(如果作为程序流的一部分使用,这本质上是伪装的gotos)所搁置,那么遵循流程就容易多了。你只需要想的更少

我认为这是一件好事。“智能”代码很难让人理解


另一方面,JVM要聪明得多,为提高效率而编码通常是没有回报的。

纯粹从效率的角度来看,给出您的代码示例,我认为这取决于您希望看到坏值的频率。如果坏值不是很少见,那么比较会更快,因为异常是昂贵的。但是,如果坏值非常罕见,则使用异常可能会更快


不过,底线是,如果您正在寻找性能,请分析您的代码。这段代码甚至可能不值得关注。如果是的话,那么两种方法都试一下,看看哪个更快。同样,这取决于您希望看到错误值的频率。

通常,人们会认为try-catch更昂贵,因为它在代码中看起来更重,但这完全取决于JIT。我的猜测是,如果没有一个真实的案例和一些性能度量,就不可能判断。比较可能更昂贵,尤其是当您有许多值时,例如,或者因为您必须调用
equals()
,因为
==
在许多情况下都不起作用


至于您应该选择哪一个(如“代码样式”),我的回答是:确保用户在失败时收到有用的错误消息。其他任何东西都是品味的问题,我不能给你规则。

我能找到的关于抛出异常的成本的信息非常少。很明显,一定有一些,您正在创建一个对象,可能正在获取堆栈跟踪信息

在您谈论的具体示例中:

if (value1 == badvalue || value1 == badvalue2 || ...) {
      result = specificError;
 } else {
      DoSomeActionThatFailsIfValue1IsBad(value1);
      // ...
      result = success;
 }
对于我来说,这里的问题是,如果(可能不完全)在调用方中复制应该由您调用的方法拥有的逻辑,您将面临危险

因此,我不会进行这些检查。您的代码不是在执行实验,而是在执行
public int IsAuthenticated(String username, String password)
{

     if(!Validated(username,password)
     {
          // just an error
          // log it
          return -2;   
     }

     // contacting the Database here
     if cannot connect to db
     {
          // woww this is HUUGE
          throw new DBException('cannot connect'); // or something like that
     }

     // validate against db here
     if validated, return 0;

    // etc etc

}
public void setAge(int age)
{
    if(age < 0)
    {
        throw new IllegalArgumentException("Array can't be negative");
    }

    this.age = age;
}
public void readFile(String filename) throws IOException
{
   File myfile = new File(filename);
   FileInputStream fis = new FileInputStream(myfile);

   //do stuff

   fis.read();

   //do more stuff
}