返回值与返回错误代码?

时间:2011-10-10 22:37:00

标签: exception exception-handling error-handling error-code

这是一般编程问题,与任何特定语言无关。

新程序员通常会编写一个计算某个值的方法,然后返回值:

public Integer doSomething()
{
   // Calculate something
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

但是当计算something期间发生异常时,处理异常的最佳方法是什么,特别是在给用户反馈时?如果你对something的计算进行试验/捕获,如果发现异常,你会返回什么?没有计算,所以你返回null?一旦你返回它(无论它是什么),你是否需要在父方法中进行另一次try / catch,检查是否返回了有效值?如果没有,那么请确保给用户一些反馈?

我听过表格的两边都有关于永远不会返回值的论点,而是将计算值设置为指针或全局变量,而只返回方法中的错误代码,然后(在父方法中)简单地处理相应的错误代码。

是否有最佳做法或方法?是否有任何好的资源可以访问以了解更多关于处理此问题的最佳方法?

更新澄清

请考虑以下代码:

public void main()
{
  int myValue = getMyValue();

  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  try
  {
    // Calculate some value
  } catch (exception e) {
    // ??
  }
  return value;
}

我调用该方法获取一些int值,然后我返回它。回到main(),我对值进行了一些操作,比如在本例中的Log中显示它。通常我会在用户界面中显示该值。

无论如何,如果在getMyValue()中捕获到异常,那么value会被返回,但它是否为空?那么main()会发生什么?我是否必须测试它是否也是main()中的有效值?

我需要程序来相应地处理错误并继续。以下有人建议在getMyValue()方法中在UI中显示相应的信息。我看到两个潜在的问题:

  1. 似乎我将业务逻辑与(在这种情况下)UI的逻辑混合在一起。
  2. 我必须将MyUIObject的引用传递给getMyValue()或其他东西,以便我可以在函数中访问它。在上面的简单示例中没有什么大不了的,但是如果有一个UI元素的BUNCH需要根据getMyValue()中发生的事情进行更新或更改,那么传递它们可能会有点多......
  3. 我已经阅读了很多关于所有这些的基本原理,但我似乎无法找到上述情况的直接答案。我感谢任何帮助或见解。

3 个答案:

答案 0 :(得分:2)

我认为你不太了解例外情况。

如果抛出异常,则 not 正常从函数返回:

public Integer doSomething()
{
   throw new my_exception();
   // The following code does NOT get run
   return something;
}

public void main()
{
  Integer myValue = doSomething();
}

例外的主要优点是:

  • 您可以编写代码,就像所有内容都成功一样,这通常更清晰
  • 例外很难被忽视。如果未处理异常,通常会出现明显且响亮的错误,并显示堆栈跟踪。这与错误代码形成鲜明对比,在错误代码中忽略错误处理非常容易。

我建议使用this post by Eric Lippert,它讨论异常以及何时处理它们并且不适合处理它们。


更新(回应评论):

您可以绝对处理异常并继续,通过捕获异常来执行此操作。

例如:

try
{
   // Perform calculation
}
catch (ExceptionType ex)
{
   // A problem of type 'ExceptionType' occurred - you can do whatever you
   // want here.
   // You could log it to a list, which will be later shown to the user,
   // you could set a flag to pop up a dialog box later, etc
}

// The code here will still get run even if ExceptionType was thrown inside
// the try {} block, because we caught and handled that exception.

关于这一点的好处是你知道出现了什么问题(来自异常类型),以及细节(通过查看ex中的信息),所以你 希望拥有做正确事情所需的信息。


更新2 以响应您的修改:

您应该在能够以您想要的方式响应的层处理异常。对于您的示例,您是正确的,您不应该在代码中深入捕获异常,因为您无法访问UI等,因此您无法真正做任何有用的事情。

此版本的示例代码如何:

public void main()
{
  int myValue = -1; // some default value
  String error = null; // or however you do it in Java (:

  try
  {
    getMyValue();
  }
  catch (exception e)
  {
    error = "Error calculating value. Check your input or something.";
  }

  if (error != null)
  {
    // Display the error message to the user, or maybe add it to a list of many
    // errors to be displayed later, etc.
    // Note: if we are just adding to a list, we could do that in the catch().
  }

  // Run this code regardless of error - will display default value
  // if there was error.
  // Alternatively, we could wrap this in an 'else' if we don't want to
  // display anything in the case of an error.
  MyUIObject whatever = new MyUIObject();
  whatever.displayValue(myValue); // Display the value in the UI or something
}

public Integer getMyValue()
{
  // Calculate some value, don't worry about exceptions since we can't
  // do anything useful at this level.
  return value;
}

答案 1 :(得分:0)

您写道:

  

我听过表格的两边都有关于永远不会返回值的论点,而是将计算值设置为指针或全局变量,而只返回方法中的错误代码,然后(在父方法中)简单地处理相应的错误代码。

<强> [编辑] 实际上,excetion可以被视为错误代码,它伴随着相关消息,并且您作为程序员应该知道您的异常必须被捕获,处理并最终显示给用户的位置。只要您让异常传播(在被调用函数的堆栈中向下),就不会使用返回值,因此您不必关心处理相关的遗漏值。良好的异常处理是一个非常棘手的问题。

正如jwd回答的那样,我没有看到在方法中引发异常然后在同一方法中处理excpetion只是为了返回错误值。澄清:

 public Integer doSomething(){

     try{

         throw new my_exception();}

     catch{ return err_value;} 

     }

没有意义。

答案 2 :(得分:0)

异常是面向对象语言(OOL)的属性。如果您使用OOL,您应该更喜欢例外。它比返回错误代码要好得多。您可以找到很好的示例,错误代码方法如何生成比基于异常的代码更长的源代码。例如,如果您想要读取文件并对其执行某些操作并以不同的格式保存。你可以在没有异常的情况下在C中完成它,但你的代码将充满if(error)...语句,也许你会尝试使用一些goto语句,也许是一些宏来缩短它。但也绝对不透明,难以理解。此外,您通常只是忘记测试返回值,这样您就不会看到错误并继续执行程序。这不好。另一方面,如果您使用OOL编写并使用异常,则源代码将重点关注“在没有错误时该怎么做”,并且错误处理位于不同的位置。只有一个错误处理代码可用于许多可能的文件错误。源代码更短,更清晰等。

我个人绝不会尝试在面向对象的语言中返回错误代码。一个例外是C ++,其中异常系统有一些限制。