И с точки зрения 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;
}
Кстати, было бы альтернативные способы получения, что в Java. Можно было бы использовать Integer вместо int, а другой - поместить int внутри массива и передать его методу. –
Да, именно поэтому я упомянул о «желании вернуть примитивную» часть. Это возможно, но никогда не бывает аккуратно. – Calum