Y desde el punto de vista de Java, simplemente señalando que le falta un método similar tal , a pesar de que podíamos conseguir a través de cosas como:
boolean isInteger = Pattern.matches("^\d*$", myString);
predecir si Integer.parseInt(myString)
lanzaría una Excepción, hay más trabajo por hacer. The String podría comenzar con un -
. Además, un int no puede tener más de 10 dígitos significativos. Entonces, una expresión más confiable sería ^-?0*\d{1,10}$
. Pero incluso esta expresión no predeciría todas las excepciones porque todavía es demasiado impreciso.
Para generar una expresión regular confiable es posible. Pero sería muy largo. También es posible implementar un método que determina con precisión si parseInt arrojaría una excepción. Se podría tener este aspecto:
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;
}
No sé qué versión es más eficiente sin embargo. Y depende principalmente del contexto qué tipo de controles son razonables.
En C# a compruebe si se puede convertir una cadena, utilizaría TryParse. Y si devuelve verdadero, entonces como subproducto, obtuvo convertido al mismo tiempo. Esta es una característica clara y no veo un problema con solo volver a implementar parseInt para devolver nulo en lugar de lanzar una excepción.
Pero si no quiere volver a implementar el método de análisis, podría ser bueno tener a mano un conjunto de métodos que pueda usar según la situación. Ellos podrían este aspecto:
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;
}
Por cierto, no habría formas alternativas para conseguir que en Java. Uno sería el uso de Integer en lugar de int y el otro para poner int dentro de una matriz y pasarla al método. –
Sí, es por eso que mencioné la parte "mientras queriendo devolver una parte primitiva". Es posible, pero nunca limpio, esencialmente. – Calum