【问题标题】:Java class design and handling ExceptionsJava类设计和异常处理
【发布时间】:2014-10-26 07:34:55
【问题描述】:

我的getChoice() 方法从控制台获取字符输入并将字符返回给main()getChoice() 是否应该抛出异常,让main() 处理它:

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

或者应该getChoice()捕获异常,处理它并返回一个字符:

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;
}

从设计的角度来看,哪种方法更好? 有没有更好的方法来做到这一点?

【问题讨论】:

  • 谁在乎?!?关闭你的资源!哇!!!!!!
  • @CandiedOrange 实际上,在这种情况下,关闭 System.in 是不可取的。
  • 嗯,看来你有道理:stackoverflow.com/questions/17174752/…我谦虚地撤回我的 WHAAAA

标签: java exception methods class-design ioexception


【解决方案1】:

对我来说,抛出异常似乎是更好的选择,因为在发生异常的情况下返回默认值(或错误代码,如果您愿意)不会让调用者知道在读取用户输入时出现错误.使用像 (char)0 这样的返回值作为错误代码会让您回到没有异常处理的语言。

也就是说,您应该考虑捕获 IOException 并抛出您自己的一些异常,以描述错误。

例如:

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;
}

【讨论】:

    【解决方案2】:

    第一个更好。异常是用来表示异常情况的。返回值不是。在第二个中,调用者必须知道在出现问题时返回 0。而且,0是一个有效的char值,无法区分“输入为'0'”和“出现异常”。

    并不是说使用 BufferedReader 读取单个字符是完全过分的:没有什么可以缓冲的。

    【讨论】:

      【解决方案3】:

      这取决于你喜欢的风格。在您特定的非常简单的情况下,我建议使用第一种方法,即只抛出异常。

      原因如下。有两种情况:

      1. main 确实知道如何处理异常情况(抛出异常或返回非法值)
      2. main 与本案无关。

      如果 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
            }
      }
      

      但是,如果您返回 0,您实际上两次关心该值:第一次进入 getChoice(),第二次进入 main(),这会在这两种方法之间产生额外的耦合。

      然而,很多时候即使main() 也与错误输入无关。在这种情况下,您的方法是:

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

      如您所见,代码要简单得多。 因此,您的选择取决于您的调用者是否有理由捕获异常。原因可以是处理它或包装它,但其他类型除外。

      【讨论】:

        【解决方案4】:

        一个方法应该在什么时候抛出异常?典型的建议是仅在异常 情况下才使用它们。但是什么算作异常的情况呢?我提出了一个不同的规则(我相信最初是由 Herb Sutter 提出的):当且仅当,替代方案是不执行指定的方法。这将问题从模糊(什么是例外)转变为可能精确的问题(规范是怎么说的)。

        那么您的getChoice 方法的规范是什么?它读到一个选择。考虑该方法无法读取选择的情况。该方法不能return 选择该情况,因为它未能读取该选择。所以它必须改为抛出异常。当read 操作抛出IOException 时,getChoice 方法已尝试但未能读取选择。所以它必须抛出一个异常。因此,该方法不应尝试自己处理IOException,而应让其调用者处理它。

        【讨论】:

          猜你喜欢
          • 2011-07-02
          • 1970-01-01
          • 1970-01-01
          • 2013-02-02
          • 1970-01-01
          • 2012-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多