当前位置: 首页 > 知识库问答 >
问题:

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

苏墨竹
2023-03-14

我正在从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个答案

晋鹤轩
2023-03-14

更清楚地解释这本书。

表达式中args[0]的实现包含检查args的长度至少为1,否则将创建异常

指:

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

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

if (args.length > 0

否则它将创建一个异常

无需检查

据推测,他接下来会采用改进的尝试,捕获方法,这就是通常处理异常的方式(如此处的另一个答案所示)

微生俊
2023-03-14

糟糕代码的标志之一是有很多错误。“工作量很大”的原因是这本书的作者是一个糟糕的程序员。

以下是优秀程序员编写完全相同但代码较少的代码的方式:

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()方法用于检查字符串是否仅由数字组成。

需要注意的是,当调用< code>Integer.parseInt()时,“检查字符串是否只有数字”并不能防止出现异常——如果您向它传递一个大于< code>2147483647的数字(即< code>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.");
    }          
}

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

 类似资料:
  • 首先,如果我搞砸了我的描述,我是新手,基本上我在正确使用node上遇到了麻烦,我跟随了youtube教程,直到老师告诉我们重新运行我们的代码,当我尝试使用他做的代码时,我得到了这个错误。 我搜索了错误中提到的,但找不到文件夹,我认为它是问题的一部分。 我尝试了很多方法,例如使用,这导致了这个cmd日志; 我还尝试删除我的和,但没有结果。 任何帮助都是感激的,并提前表示感谢:) 编辑:这里是pack

  • 我正在尝试使用2个docker容器设置一个基本模型(用于训练): 一个是nginx 一个是詹金斯 nginx被用作反向容器(下一步将是https前端)。詹金斯应该是公开的www.devportal.org:90/ci 我已经部分成功了。我的意思是我可以用给定的地址访问它。但是... > < li> 当我尝试与管理员用户连接时,出现登录页面。但是当填写用户/密码时,我被重定向到http://www.

  • 我正在重构前一段时间编写的一些代码,试图通过实现一些设计模式使其更加可靠。具体来说,我尝试使用构建器模式实例化GUI对象。 以下是“产品”的代码: 这是“混凝土建造者”的代码: 以及“抽象生成器”接口的代码: 现在,这里是“Director”的当前工作构建方法: 酷,那有什么问题吗?好吧,这可能最终无关紧要,但这是我对该方法的实际首选实现: 看看它看起来有多干净?唯一的问题是JetBrains无论

  • 我试图创建一个Java正则表达式,如果字符串末尾有奇数个反斜杠(),它将返回true,如果偶数,则返回false。 这是我的正则表达式 当我编译代码时,我得到以下异常 线程“main”java.util.regex.PatternSyntaxException中的异常:索引15^([^])(\)附近的未关闭字符类\$ 如果我使用M模式编译并运行良好,则可以使用反斜杠代替反斜杠 我知道这是一个逃避的

  • 说明: 这实际上是一个诡计问题,因为这段代码不会编译!正如您在第1章中所记得的,浮点文字被假定为双倍,除非后缀有一个f,如2.1f。如果正确地将该值设置为2.1F,那么升级将与上一个示例类似,两个操作数都升级为double,结果将是一个double值。 但我不明白。如果浮动y=2.1;假设是双倍,则不需要将变量y提升到双倍。而我更困惑的是下一个问题,那就是: