1

这是一个通用的编程问题,与任何特定语言无关。

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

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

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

但是当计算过程中出现异常时something,处理异常的最佳方法是什么,尤其是在给用户反馈时?如果您对计算进行 try/catchsomething并且如果捕获到异常,您会返回什么?没有计算任何东西,所以你返回 null 吗?一旦你返回它(不管它是什么),你是否需要在父方法中再次尝试/捕获来检查是否返回了有效值?如果没有,那么确保给用户一些反馈?

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

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

更新澄清

考虑以下代码:

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(),我对这个值做了一些事情,比如在这种情况下在日志中显示它。通常我会在 UI 中为用户显示该值。

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

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

  1. 似乎我会将业务逻辑与(在这种情况下)UI 的逻辑混合在一起。
  2. 我必须传递MyUIObject对 thegetMyValue()或其他东西的引用,以便我可以从函数内部访问它。在上面的简单示例中,这没什么大不了的,但是如果有一堆 UI 元素需要根据发生的情况进行更新或更改,那么getMyValue()将它们全部传递可能会有点多......

我已经阅读了很多关于这一切的基础知识,但我似乎无法为上述情况找到一个直接的答案。我感谢任何帮助或见解。

4

3 回答 3

2

我认为您不太了解异常。

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

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

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

例外的主要优点是:

  • 您可以编写代码,就好像一切都成功了,这通常更清晰
  • 例外是难以忽视的。如果异常未处理,通常会给出明显而响亮的错误,并带有堆栈跟踪。这与错误代码形成对比,在错误代码中,忽略错误处理比不忽略错误处理要容易得多。

我推荐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;
}
于 2011-10-10T22:42:57.340 回答
0

你写了:

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

[编辑] 实际上,异常可以看作是错误代码,它与相关消息一起出现,你作为程序员应该知道你的异常必须在哪里被捕获、处理并最终显示给用户。只要您让异常传播(在被调用函数的堆栈中向下),就不会使用返回值,因此您不必关心处理相关的缺失值。良好的异常处理是一个相当棘手的问题。

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

 public Integer doSomething(){

     try{

         throw new my_exception();}

     catch{ return err_value;} 

     }

是没有意义的。

于 2011-10-10T22:44:53.380 回答
0

异常是面向对象语言 (OOL) 的属性。如果您使用 OOL,您应该更喜欢异常。这比返回错误代码要好得多。您可以找到很好的示例,错误代码方法如何生成比基于异常的代码更长的源代码。例如,如果您想读取文件并对其进行处理并以不同的格式保存。您可以在 C 中毫无例外地做到这一点,但是您的代码将充满 if(error)... 语句,也许您会尝试使用一些 goto 语句,也许使用一些宏来使其更短。但也绝对不透明且难以理解。此外,您通常会忘记测试返回值,因此您看不到错误并且程序继续运行。这不好。另一方面,如果您使用 OOL 编写并使用异常,则您的源代码侧重于“

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

于 2011-10-10T22:54:29.487 回答