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

r55awzrz  于 2022-11-20  发布在  Java
关注(0)|答案(2)|浏览(133)

我正在从 *Java学习Java:约翰·莱瑟姆,我有一点困惑。
我们有一个程序,它从命令行参数中获取当前年龄,并计算下一年的年龄。

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,否则会创建Exception。同时,Integer.parseInt()中的代码肯定会检查参数的每个字符是否为数字。--]
我不明白他在括号[----]里的意思。

jchrr9hc

jchrr9hc1#

糟糕代码的一个标志是代码量很大,之所以说“代码量很大”,是因为这本书的作者是一个糟糕的程序员。
下面是一个优秀的程序员如何编写代码来做完全相同的事情,但用更少的代码:

public static void main(String[] args) {
   if (args.length == 0 || !args[0].matches("\\d{1,3}")) // age must be in range 0-999
       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.");
    }          
}

这是完全鲁棒且甚至再次更少编码。

shstlldc

shstlldc2#

把书解释得更清楚一点。
表达式中args[0]的实现包含参数长度至少为1的检查,否则将创建异常
指的是:

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

包含参数长度至少为一的检查

if (args.length > 0

否则将创建异常
如果不检查> 0,则在没有参数输入的情况下将发生ArrayIndexOutOfBoundsException
据推测,他接下来将采用改进的try, catch方法,这是通常处理Exceptions的方法(* 如此处的另一个答案所示 *)

相关问题