Исключения не должны использоваться для управления потоком, хотя авторы Java затруднили не использовать NumberFormatException
таким образом.
В классе java.util.Scanner
есть метод hasNextDouble
, позволяющий проверить, может ли String
читаться как двойное число.
Под капотом Scanner
использует регулярные выражения (с помощью предварительно скомпилированных шаблонов), чтобы определить, можно ли String
преобразовать в целое число или число с плавающей запятой. Шаблоны скомпилированы в методе buildFloatAndDecimalPattern
, который вы можете посмотреть по адресу GrepCode здесь .
Предварительно скомпилированный шаблон имеет дополнительное преимущество в том, что он быстрее, чем при использовании блока try / catch.
Вот метод, упомянутый выше, в случае, если GrepCode исчезнет однажды:
private void buildFloatAndDecimalPattern() {
// \\p{javaDigit} may not be perfect, see above
String digit = "([0-9]|(\\p{javaDigit}))";
String exponent = "([eE][+-]?"+digit+"+)?";
String groupedNumeral = "("+non0Digit+digit+"?"+digit+"?("+
groupSeparator+digit+digit+digit+")+)";
// Once again digit++ is used for performance, as above
String numeral = "(("+digit+"++)|"+groupedNumeral+")";
String decimalNumeral = "("+numeral+"|"+numeral +
decimalSeparator + digit + "*+|"+ decimalSeparator +
digit + "++)";
String nonNumber = "(NaN|"+nanString+"|Infinity|"+
infinityString+")";
String positiveFloat = "(" + positivePrefix + decimalNumeral +
positiveSuffix + exponent + ")";
String negativeFloat = "(" + negativePrefix + decimalNumeral +
negativeSuffix + exponent + ")";
String decimal = "(([-+]?" + decimalNumeral + exponent + ")|"+
positiveFloat + "|" + negativeFloat + ")";
String hexFloat =
"[-+]?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP][-+]?[0-9]+)?";
String positiveNonNumber = "(" + positivePrefix + nonNumber +
positiveSuffix + ")";
String negativeNonNumber = "(" + negativePrefix + nonNumber +
negativeSuffix + ")";
String signedNonNumber = "(([-+]?"+nonNumber+")|" +
positiveNonNumber + "|" +
negativeNonNumber + ")";
floatPattern = Pattern.compile(decimal + "|" + hexFloat + "|" +
signedNonNumber);
decimalPattern = Pattern.compile(decimal);
}