简体   繁体   English

扩展java.util.Scanner

[英]Extending java.util.Scanner

Suppose I would like to add a method to Scanner called nextPositiveInt() which is similar to nextInt() except that when a negative integer is detected, a custom InputNegativeException is thrown. 假设我想向Scanner添加一个名为nextPositiveInt()的方法,它与nextInt()类似,只是当检测到一个负整数时,抛出一个自定义的InputNegativeException

Why would I want to do this when there are solutions that utilise hasNextInt() ? 当有解决方案使用 hasNextInt()时,为什么我要这样做呢? While being a little less concise, it seems a whole lot tidier and more logical given the purpose of exceptions. 虽然不那么简洁,但考虑到例外的目的,它似乎更整洁,更合乎逻辑。 For example: 例如:

Extended Scanner method: 扩展扫描仪方法:

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() method: 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);

So assuming you aren't already firing up a response telling me why this is a very bad idea (if it is, please do; I imagine there might be some objection regarding putting validation in Scanner) I'm confused about how to go about this. 因此,假设您尚未发出响应,告诉我为什么这是一个非常糟糕的主意(如果是,请执行;我想可能有一些关于在扫描仪中进行验证的异议)我很困惑如何去做这个。 I guess I need to replicate the body of nextInt() in nextPositiveInt() with some minor changes? 我想我需要在nextPositiveInt()复制nextInt()的主体并进行一些小的更改? Can you even source the body of nextInt() anywhere? 你甚至可以在任何地方找到nextInt()的主体吗?

I apologise that I have no code to show any effort I've made but I'm not sure where to start. 我很抱歉我没有代码表明我已经做出任何努力,但我不知道从哪里开始。

You cannot extend Scanner since it's final : 您无法扩展Scanner因为它是final

public final class Scanner
extends Object
implements Iterator<String>

What I would do is have a helper method in one of my classes: 我要做的是在我的一个类中有一个辅助方法:

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

and would use it like so: 并会像这样使用它:

int val = ensureNonNegative(scanner.nextInt());

Althought Scanner class is final and you cann't extend it there exist another solution. 虽然Scanner类是最终的,你不能扩展它存在另一种解决方案。 You can use Delegation pattern . 您可以使用委托模式

Also as Scanner class has all nessasary methods public you can easily copy original method and make a little change. 此外,由于Scanner类具有公开的所有nessasary方法,您可以轻松复制原始方法并进行一些更改。 See source code of Scanner class the only thing you should change is regexp used for matching string in order to exclude negative ints. 请参阅Scanner类的源代码,您应该更改的唯一内容是用于匹配字符串的regexp以排除负的int。

Source code of 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());
    }
}

You should change only: 你应该只改变:

String s = next(integerPattern());

For you purposes you can hardcode regexp. 为了您的目的,您可以硬编码regexp。 Original regexp can easily be caught on debug. 原始正则表达式可以很容易地在调试时捕获。

Definitely it wouldn't be the best solution in terms of realization - a lot of code to write and many copy-paste, but it would be easy and nice to use. 当然,它不是实现方面的最佳解决方案 - 需要编写大量代码和许多复制粘贴,但使用起来会很简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM