【问题标题】:Java try/catch - either "return isn't found" or "variable isn't initialized"?Java try/catch - “未找到返回”或“未初始化变量”?
【发布时间】:2012-10-07 22:24:20
【问题描述】:

我已经盯着这个看了好几个小时了,想不出解决办法;我通常使用正则表达式处理这种类型的验证,但我尝试使用内置解决方案进行更改(显然,我不经常这样做):

private static double promptUserDecimal(){
    Scanner scan = new Scanner(System.in);
    System.out.println("Enter a decimal");
    try{
        double input2 = Double.parseDouble(scan.nextLine());
        return input2;
    } catch(NumberFormatException e){
        System.out.println("Sorry, you provided an invalid option, please try again.");
    }
}

这个错误是编译器找不到“返回”,所以我得到一个编译错误。如果我将“return”放在 try/catch 之外,我需要声明/初始化“input2”,这违背了操作的目的。任何帮助表示赞赏...

【问题讨论】:

  • 您捕获了异常,打印出一条消息,但是该方法仍然从catch 块继续。编译器抱怨如果 catch 块被命中,你不会返回(并非所有路径都返回)。

标签: java compiler-errors


【解决方案1】:

如果你想让用户“请再试一次”,听起来你需要一个循环:

private static double promptUserDecimal(){
    final Scanner scan = new Scanner(System.in);

    // Ask for input until we get something valid
    while (true) {  // Terminated by return within
        System.out.println("Enter a decimal");
        try {
            return Double.parseDouble(scan.nextLine());
        } catch(NumberFormatException e){
            System.out.println("Sorry, you provided an invalid option, please try again.");
            // No return, so the loop will run again
        }
    }
}

【讨论】:

  • 我有一个问题。这个sn-p编译?
  • OP:我喜欢这种无人值守脚本的解决方案。
【解决方案2】:

你需要这样的东西:

double input2;
try{
  //read input2
}catch( ... ){
  //... log AND assign a value to input2 in case of invalid input
}
return input2;

【讨论】:

  • 您可以在声明变量时指定默认的错误值。
【解决方案3】:

catch 部分中抛出异常。无论你在哪里调用promptUserDecimal 方法,捕获任何异常并在那里打印消息:

public static void main(String[] args) {

    double d = 0.0;
    while (double == 0) {
        try {
            d = promptUserDecimal();
        } catch (NumberFormatException e) {
            //log the message...
            d = 0.0;
        }
    }
}

private static double promptUserDecimal() throws NumberFormatException {
    Scanner scan = new Scanner(System.in);
    System.out.println("Enter a decimal");
    return Double.parseDouble(scan.nextLine());
}

这将是一个更好的方法,因为您让promptUserDecimal 只关心处理读取双精度值。您必须尝试将每个类和方法分开,以满足其设计的特定目的。

【讨论】:

  • +1 但如果你无论如何要抛出NumberFormatException,那么你不需要抓住它。一开始不要抓,让parseDouble抛出异常。
【解决方案4】:

让你的方法抛出异常或返回 nan。

【讨论】:

    【解决方案5】:

    您需要从(或在接球后)返回或扔东西。从您对用户的输出来看,您似乎只想再次做同样的事情。只需再次调用该方法并返回结果即可。

    private static double promptUserDecimal(){
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a decimal");
        try{
            double input2 = Double.parseDouble(scan.nextLine());
            return input2;
        } catch(NumberFormatException e){
            System.out.println("Sorry, you provided an invalid option, please try again.");
            return promptUserDecimal();
        }
    }
    

    【讨论】:

    • 对“重试”使用递归有点奇怪;每次它都会在堆栈上建立更多的挂起调用。尽管用户不太可能输入错误输入的次数足以导致堆栈溢出,但循环会更有意义。
    【解决方案6】:

    你可以在你的 catch 块中抛出一个异常。即,

    private static double promptUserDecimal() throws OopsException {
        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a decimal");
        try{
            double input2 = Double.parseDouble(scan.nextLine());
            return input2;
        } catch(NumberFormatException e){
            System.out.println("Sorry, you provided an invalid option, please try again.");
            throw new OopsException();
        }
    }
    

    然后,每次他们提供无效输入时,您都可以在调用方法的地方捕获并处理它。

    【讨论】:

      【解决方案7】:
      private static double promptUserDecimal(){
          Scanner scan = new Scanner(System.in);
          System.out.println("Enter a decimal");
          double input2 = 0.0; // <-- explicit initialization
          try{
              double input2 = Double.parseDouble(scan.nextLine());
          } catch(NumberFormatException e){
              System.out.println("Sorry, you provided an invalid option, please try again.");
          }
          return input2;
      }
      

      【讨论】:

        【解决方案8】:

        列出的一些解决方案将解决编译器问题,但第一步是退后一步,问“如果发生 NumberFormatException,我想做什么?”

        一种选择是通过重新抛出 NumberFormatException 或将其包装在 RuntimeException 中以使其不受检查来传播异常。这意味着调用代码必须处理它,否则用户将看到堆栈跟踪。如果你走这条路,你甚至不需要在你的方法中使用 try catch。您可以在方法签名上声明“抛出 NumberFormatException”并让它在上游处理。

        另一种选择是返回 null,方法是使用“return null”作为 catch 块中的最后一个语句,或者返回 null 作为方法中的最后一个语句。这是一个糟糕的选择,因为调用代码和/或最终用户不会获得他们需要的信息,即“输入了一个非数字作为输入”。

        我会选择选项一,并通过告诉用户 scan.nextline + " 未被识别为有效的双精度来处理异常。"

        【讨论】:

          猜你喜欢
          • 2014-12-13
          • 1970-01-01
          • 1970-01-01
          • 2016-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-31
          • 1970-01-01
          相关资源
          最近更新 更多