需要帮助理解作者对一段代码的论证

时间:2016-01-04 17:28:20

标签: java exception

我正在从 Java学习Java:Just in Time,John Latham 。我有点困惑。

我们有一个程序,它从命令行参数中获取当前年龄并计算明年的年龄。

public class AgeNextYear
{
  public static void main(String[] args)
  {
    int ageNow = Integer.parseInt(args[0]);
    int ageNextYear = ageNow + 1;

    System.out.println("Your age now is " + ageNow);
    System.out.println("Your age next year will be " + ageNextYear);
  } // main
} // class AgeNextYear

用户有两种方法可以使该程序失败。首先,他们可能没有 命令行参数,因此在尝试访问args [0]时会出现问题。 其次,它们可能提供的参数不是整数的字符串表示形式,因此Integer.parseInt()方法将无法 将该值解释为int。 然后,为了避免此代码中的两个可能的异常,我们可以向AgeNextYear程序添加一些代码来检查用户输入的有效性。然后代码是

 public class AgeNextYear
 {
  // Return true if and only if given string is all digits and non empty.
  private static boolean isNonEmptyDigits(String shouldBeDigits)
  {
    boolean okaySoFar = shouldBeDigits.length() != 0;
    int index = 0;
    while(okaySoFar && index < shouldBeDigits.length())
    {
      okaySoFar = Character.isDigit(shouldBeDigits.charAt(index));
      index ++;
    } // while
    return okaySoFar;
  } // isNonEmptyDigits


  // Check argument and compute result or report error.
  public static void main(String[] args)
  {
    if(args.length > 0 && isNonEmptyDigits(args[0]))
    {
      int ageNow = Integer.parseInt(args[0]);
      int ageNextYear = ageNow + 1;

      System.out.println("Your age now is " + ageNow);
      System.out.println("Your age next year will be " + ageNextYear);
    } // if
    else
      System.out.println("Please supply your age, as whole number.");
  } // main

} // class AgeNextYear

然后,这本书的作者说,

  

虽然我们确实使该计划具有可靠性   例外情况,我们不应该满意这种方法。首先,它   相当多的工作 - 该计划的规模翻了一番。 [ -   其次,我们的代码新部分所做的检查也是如此   程序中导致例外的部分所造成的   第一名。也就是说,在表达式中实现args [0]   包含一个检查args的长度至少为1,否则它   将创建一个例外。此外,Integer.parseInt()中的代码是   一定要检查参数的每个字符是否为数字。 - ]

我不明白括号中的含义[ - - ]。

2 个答案:

答案 0 :(得分:2)

糟糕代码的一个标志就是它有很多。 “这是很多工作”的原因是因为这本书的作者是一个糟糕的程序员。

这是一个优秀的程序员如何编写完全相同的代码,但代码更少:

public static void main(String[] args) {
   if (args.length == 0 || !args[0].matches("\\d+"))
       System.out.println("Please supply your age, as whole number.");
   else
       System.out.println("Your age now is " + args[0] + "\nYour age next year will be " + (Integer.parseInt(args[0]) + 1));
}

这是整个程序顺便说一句。

请注意您根本不需要ageNowageNextYear个变量,String.matches()方法用于检查字符串是否仅由数字组成。

应该注意的是,“检查字符串是否只是数字”在调用Integer.parseInt()可防止异常 - 如果您传递的数字大于2147483647 (即Integer.MAX_VALUE)它会爆炸。

如果您需要适当的保护,请抓住预期的例外情况:

public static void main(String[] args) {
    try {
        System.out.println("Your age now is " + args[0] + "\nYour age next year will be " + (Integer.parseInt(args[0]) + 1));
    } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
        System.out.println("Please supply your age, as whole number.");
    }          
}

这是完全健壮的,甚至更少的代码。

答案 1 :(得分:1)

更清楚地解释一下这本书。

  

表达式中args[0]的实现包含一个检查,即args的长度至少为1,否则会产生异常

指的是:

if(args.length > 0 && isNonEmptyDigits(args[0])) //the expression
    {
  

包含args长度至少为1的检查

if (args.length > 0
  

否则会产生异常

如果没有> 0的检查,如果没有参数输入,则会发生ArrayIndexOutOfBoundsException

据推测,他接下来将采用改进的try, catch方法,这通常是Exceptions的处理方式(,如此处的其他答案所示