简体   繁体   English

Java类设计和处理异常

[英]Java class design and handling Exceptions

My getChoice() method takes a char input from the console and returns the char to main() . 我的getChoice()方法从控制台获取一个char输入并将char返回给main() Should getChoice() just throw the exception and let main() deal with it: 应该getChoice()只是抛出异常并让main()处理它:

static char getChoice() throws IOException
{
    BufferedReader br = new 
    BufferedReader(new InputStreamReader(System.in));
    return (char)br.read();
}

Or should getChoice() catch the exception, deal with it and return a char: 或者应该getChoice()捕获异常,处理它并返回一个char:

static char getChoice() 
{
    BufferedReader br = new 
    BufferedReader(new InputStreamReader(System.in));
    char temp;
    try {
        temp = (char)br.read();
    } catch(IOException exc) {
        System.out.println("Invalid Input");
        temp = (char)0;
    }
    return temp;
}

Which approach is better from the designing perspective? 从设计角度来看哪种方法更好? Is there a better way to do this? 有一个更好的方法吗?

Throwing an exception seems like the better option to me, since returning a default value (or error code, if you like) in case of an exception does not let the caller know there was an error while reading the input from the user. 抛出异常似乎对我来说是更好的选择,因为如果发生异常,返回默认值(或错误代码,如果你愿意)不会让调用者知道在读取用户输入时出错。 Using a return value like (char)0 as an error code brings you back to languages that don't have exception handling. 使用像(char)0这样的返回值作为错误代码可以返回到没有异常处理的语言。

That said, you should consider catching the IOException and throwing some exception of your own, that describes the error. 也就是说,你应该考虑捕获IOException并抛出一些你自己的异常,它描述了错误。

For example : 例如 :

static char getChoice() throws UserInputException
{
    BufferedReader br = new 
    BufferedReader(new InputStreamReader(System.in));
    char temp = (char)0;
    try {
        temp = (char)br.read();
    }
    catch (IOException ioEx) {
        throw new UserInputException ("Error reading input", ioEx);
    }
    return temp;
}

The first one is way better. 第一个是更好的方式。 Exceptions are meant to signal exceptional situations. 例外意味着发出异常情况。 Return values are not. 返回值不是。 In the second one, the caller has to be aware that 0 is returned in case of a problem. 在第二个中,调用者必须知道在出现问题时返回0。 And moreover, 0 is a valid char value, which makes it impossible to distinguish between "the input is '0'" and "there was an exception". 而且,0是有效的char值,这使得无法区分“输入是'0'”和“有异常”。

Not that using a BufferedReader to read a single char is a completely overkill: there is nothing to be buffered. 并非使用BufferedReader读取单个char是完全过度的:没有什么可以缓冲的。

It depends on your favorite style. 这取决于你最喜欢的风格。 In your particular, very simple case I'd suggest the first approach, ie just let exception to be thrown. 在你特别的,非常简单的情况下,我建议第一种方法,即只是抛出异常。

Here are the reasons. 原因如下。 There are 2 cases: 有2种情况:

  1. main does know how to handle the exceptinal case (either thrown exception or returned illegal value) main确实知道如何处理例外情况(抛出异常或返回非法值)
  2. main has nothing to do with this case. main与此案无关。

If main knows how to deal with this case 2 approaches are pretty similar: 如果main知道如何处理这种情况,2种方法非常相似:

// Catching exception
main(String[] args) {
   try {
       char c = getChoice();
       // do A
   } catch (IOException e) {
      // do B
   }
}


// Returning 0
main(String[] args) {
      char c = getChoice();
      if (c == 0) {
          // do B
      } else {
       // do A
      }
}

However if you are returning 0 you actually care about the value twice: first into getChoice() , second time into main() that creates additional coupling between these 2 methods. 但是如果你返回0,你实际上关心的值是两次:第一次进入getChoice() ,第二次进入main() ,在这两种方法之间产生额外的耦合。

However very often even main() has nothing to do with wrong input. 然而,即使main()与错误的输入无关。 In this case your approach is: 在这种情况下,您的方法是:

main(String[] args) throws IOException {
     char c = getChoice();
     // do A
}

As you can see the code is much simpler. 如您所见,代码更简单。 So, your choice depends on the fact whether your caller has reason to catch exception. 因此,您的选择取决于您的调用者是否有理由捕获异常的事实。 The reason can be either handle it or wrap it with exception of other type. 原因可以是处理它或包装它与其他类型的例外。

When should a method throw an exception? 应该何时抛出异常? Typical advice is to throw them only in exceptional situations. 典型的建议是仅在特殊情况下抛弃它们。 But what counts as an exceptional situation? 但是什么算是特殊情况? I suggest a different rule (originally suggested by Herb Sutter, I believe): if, and only if, the alternative would be to fail to do what the method is specified to do. 我建议一个不同的规则(最初由Herb Sutter提出,我相信):当且仅当,替代方案是不能按指定方法执行的操作。 This transforms the question from something vague (what is exceptional) to something potentially precise (what does the specification say). 这将问题从模糊(什么是例外)转变为可能精确的东西(规范说的是什么)。

So what is the specification for your getChoice method? 那么你的getChoice方法的规范是什么? It reads a choice. 它读了一个选择。 Consider the case that the method can not read the choice. 考虑该方法无法读取选择的情况。 The method must not return a choice for that case, because it has failed to read the choice. 该方法不能为该情况return选项,因为它无法读取该选项。 So it must instead throw an exception. 所以它必须抛出异常。 When the read operation throws an IOException , the getChoice method has tried but failed to read the choice. read操作抛出IOExceptiongetChoice方法已尝试但未能读取该选项。 So it must throw an exception. 所以它必须抛出异常。 Hence, the method should not try to handle the IOException itself, but should let its caller handle it. 因此,该方法不应该尝试处理IOException本身,而应该让它的调用者处理它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM