И с точки зрения Java,
просто указывая на то, что ему не хватает такого
подобный метод, несмотря на то, что мы могли бы получить
это через такие вещи, как:
boolean isInteger = Pattern.matches("^\d*$", myString);
Чтобы предсказать, если Integer.parseInt(myString)
выдаст исключение, есть еще много работы. Строка может начинаться с -
. Также int не может иметь более 10 значащих цифр. Таким образом, более надежное выражение будет ^-?0*\d{1,10}$
. Но даже это выражение не может предсказать каждое исключение, потому что оно все еще слишком неточно.
Сформировать надежное регулярное выражение можно. Но это было бы очень долго. Также возможно реализовать метод, который точно определяет, будет ли parseInt генерировать исключение. Это может выглядеть так:
static boolean wouldParseIntThrowException(String s) {
if (s == null || s.length() == 0) {
return true;
}
char[] max = Integer.toString(Integer.MAX_VALUE).toCharArray();
int i = 0, j = 0, len = s.length();
boolean maybeOutOfBounds = true;
if (s.charAt(0) == '-') {
if (len == 1) {
return true; // s == "-"
}
i = 1;
max[max.length - 1]++; // 2147483647 -> 2147483648
}
while (i < len && s.charAt(i) == '0') {
i++;
}
if (max.length < len - i) {
return true; // too long / out of bounds
} else if (len - i < max.length) {
maybeOutOfBounds = false;
}
while (i < len) {
char digit = s.charAt(i++);
if (digit < '0' || '9' < digit) {
return true;
} else if (maybeOutOfBounds) {
char maxdigit = max[j++];
if (maxdigit < digit) {
return true; // out of bounds
} else if (digit < maxdigit) {
maybeOutOfBounds = false;
}
}
}
return false;
}
Я не знаю, какая версия более эффективна. И это в основном зависит от контекста, какие проверки являются разумными.
В C # к проверьте , если строка может быть преобразована, вы бы использовали TryParse. И если он возвращает true, то в качестве побочного продукта он получает , преобразованный в то же время. Это полезная функция, и я не вижу проблемы с простым переопределением parseInt для возврата null вместо выдачи исключения.
Но если вы не хотите переопределять метод синтаксического анализа, было бы неплохо иметь под рукой набор методов, которые вы можете использовать в зависимости от ситуации. Они могут выглядеть так:
private static Pattern QUITE_ACCURATE_INT_PATTERN = Pattern.compile("^-?0*\\d{1,10}$");
static Integer tryParseIntegerWhichProbablyResultsInOverflow(String s) {
Integer result = null;
if (!wouldParseIntThrowException(s)) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
// never happens
}
}
return result;
}
static Integer tryParseIntegerWhichIsMostLikelyNotEvenNumeric(String s) {
Integer result = null;
if (s != null && s.length() > 0 && QUITE_ACCURATE_INT_PATTERN.matcher(s).find()) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
// only happens if the number is too big
}
}
return result;
}
static Integer tryParseInteger(String s) {
Integer result = null;
if (s != null && s.length() > 0) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
}
return result;
}
static Integer tryParseIntegerWithoutAnyChecks(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException ignored) {
}
return null;
}