0

假设我想向 Scanner 添加一个方法,nextPositiveInt()该方法类似于,nextInt()除了当检测到负整数时,InputNegativeException会抛出一个自定义。

当有解决方案利用 时,我为什么要这样做hasNextInt()?虽然不那么简洁,但考虑到例外的目的,它似乎更加整洁和合乎逻辑。例如:

扩展扫描仪方法:

Scanner cli = new Scanner(System.in);
boolean inputValid = false;

do
{
    System.out.println("Enter your age:");
    try
    {
        int age = cli.nextPositiveInt();
    }
    catch(InputNegativeException e)
    {
        System.out.println("You cannot specify a negative age.");
        inputValid = false;
    }
    catch(InputMismatchException e)
    {
        System.out.println("Your input must be numeric.");
        inputValid = false;
    }
} while(!inputValid);

hasNext()方法:

Scanner cli = new Scanner(System.in);

do
{
    System.out.println("Please enter a positive number!");
    while(!sc.hasNextInt())
    {
        System.out.println("That's not a number!");
        sc.next(); // this is important!
    }
    int number = sc.nextInt();
} while(number <= 0);

因此,假设您还没有回复告诉我为什么这是一个非常糟糕的主意(如果是,请这样做;我想可能有人反对在 Scanner 中进行验证)我对如何去做感到困惑这。我想我需要通过一些小的改动来复制nextInt()in的主体?nextPositiveInt()你甚至可以nextInt()找到任何地方的尸体吗?

很抱歉,我没有代码来显示我所做的任何努力,但我不确定从哪里开始。

4

2 回答 2

1

您不能扩展Scanner,因为它是final

public final class Scanner
extends Object
implements Iterator<String>

我要做的是在我的一个类中有一个辅助方法:

public static int ensureNonNegative(int val) {
  if (val >= 0) {
    return val;
  } else {
    throw new InputNegativeException(val);
  }
}

并会像这样使用它:

int val = ensureNonNegative(scanner.nextInt());
于 2012-05-23T07:05:58.723 回答
1

尽管 Scanner 类是最终的并且您不能扩展它,但存在另一种解决方案。您可以使用委托模式

此外,由于 Scanner 类公开了所有必要的方法,您可以轻松复制原始方法并进行一些更改。请参阅 Scanner 类的源代码,您唯一应该更改的是用于匹配字符串的正则表达式以排除负整数。

扫描仪源代码:

public int nextInt() {
    return nextInt(defaultRadix);
}

public int nextInt(int radix) {
    // Check cached result
    if ((typeCache != null) && (typeCache instanceof Integer)
    && this.radix == radix) {
        int val = ((Integer)typeCache).intValue();
        useTypeCache();
        return val;
    }
    setRadix(radix);
    clearCaches();
    // Search for next int
    try {
        String s = next(integerPattern());
        if (matcher.group(SIMPLE_GROUP_INDEX) == null)
            s = processIntegerToken(s);
        return Integer.parseInt(s, radix);
    } catch (NumberFormatException nfe) {
        position = matcher.start(); // don't skip bad token
        throw new InputMismatchException(nfe.getMessage());
    }
}

你应该只改变:

String s = next(integerPattern());

出于您的目的,您可以对正则表达式进行硬编码。原始正则表达式很容易在调试时被捕获。

就实现而言,这绝对不是最好的解决方案——要编写大量代码和复制粘贴,但它会很容易使用并且很好用。

于 2012-05-23T07:17:21.813 回答