try todas tipos solo propagacion mas letras las excepciones comunes catch java parsing numbers

tipos - todas las excepciones en java



Cadena a Int en Java-Probablemente datos incorrectos, necesidad de evitar excepciones (16)

Semántica más limpia (Java 8 OptionalInt)

Para Java 8+, probablemente usaría RegEx para prefiltrar (para evitar la excepción como anotaste) y luego envolveré el resultado en una opción primitiva (para lidiar con el problema "predeterminado"):

public static OptionalInt toInt(final String input) { return input.matches("[+-]?//d+") ? OptionalInt.of(Integer.parseInt(input)) : OptionalInt.empty(); }

Si tiene muchas entradas de cadena, puede considerar devolver un IntStream lugar de OptionalInt para que pueda flatMap() .

Referencias

Al ver que Java no tiene tipos anulables, ni tiene un TryParse (), ¿cómo se maneja la validación de entrada sin lanzar una excepción?

La forma habitual:

String userdata = /*value from gui*/ int val; try { val = Integer.parseInt(userdata); } catch (NumberFormatException nfe) { // bad data - set to sentinel val = Integer.MIN_VALUE; }

Podría usar una expresión regular para verificar si es analizable, pero también parece una gran sobrecarga.

¿Cuál es la mejor práctica para manejar esta situación?

EDITAR: Justificación: Se ha hablado mucho sobre SO sobre el manejo de excepciones, y la actitud general es que las excepciones se deben usar solo para escenarios inesperados. Sin embargo, creo que la entrada de usuarios malintencionados es ESPERADA, no rara. Sí, realmente es un punto académico.

Ediciones adicionales:

Algunas de las respuestas demuestran exactamente lo que está mal con SO. Ignoras la pregunta que se te hace y respondes otra pregunta que no tiene nada que ver con eso. La pregunta no es preguntar sobre la transición entre capas. La pregunta no es preguntar qué devolver si el número no se puede analizar. Por lo que sabemos, val = Integer.MIN_VALUE; es exactamente la opción correcta para la aplicación de la que se tomó este fragmento de código completamente contextual.


¿Cuál es el problema con tu enfoque? No creo que hacerlo de esa manera dañará el rendimiento de tu aplicación. Esa es la forma correcta de hacerlo. No optimice prematuramente .


Así es como lo hago:

public Integer parseInt(String data) { Integer val = null; try { val = Integer.parseInt(userdata); } catch (NumberFormatException nfe) { } return val; }

Entonces el nulo señala datos inválidos. Si quiere un valor predeterminado, puede cambiarlo a:

public Integer parseInt(String data,int default) { Integer val = default; try { val = Integer.parseInt(userdata); } catch (NumberFormatException nfe) { } return val; }


Creo que la mejor práctica es el código que muestra.

No iría por la alternativa de expresiones regulares debido a la sobrecarga.


El código anterior es malo porque es equivalente al siguiente.

// this is bad int val = Integer.MIN_VALUE; try { val = Integer.parseInt(userdata); } catch (NumberFormatException ignoreException) { }

La excepción se ignora por completo. Además, el token mágico es malo porque un usuario puede pasar en -2147483648 (Integer.MIN_VALUE).

La pregunta genérica analizable no es beneficiosa. Por el contrario, debe ser relevante para el contexto. Su aplicación tiene un requisito específico. Puedes definir tu método como

private boolean isUserValueAcceptable(String userData) { return ( isNumber(userData) && isInteger(userData) && isBetween(userData, Integer.MIN_VALUE, Integer.MAX_VALUE ) ); }

Donde puede documentar el requisito y puede crear reglas bien definidas y comprobables.


El mecanismo de excepción es valioso, ya que es la única forma de obtener un indicador de estado en combinación con un valor de respuesta. Además, el indicador de estado está estandarizado. Si hay un error, obtienes una excepción. De esta forma, no tiene que pensar en un indicador de error usted mismo. La controversia no es tanto con excepciones, sino con Excepciones Controladas (por ejemplo, las que tiene que atrapar o declarar).

Personalmente, creo que elegiste uno de los ejemplos donde las excepciones son realmente valiosas. Es un problema común que el usuario ingrese el valor incorrecto y, por lo general, deberá volver al usuario para obtener el valor correcto. Normalmente no vuelve al valor predeterminado si le pregunta al usuario; eso le da al usuario la impresión de que su entrada importa.

Si no quiere lidiar con la excepción, simplemente envuélvala en una RuntimeException (o clase derivada) y le permitirá ignorar la excepción en su código (y cancelar su aplicación cuando ocurra, eso también está bien).

Algunos ejemplos sobre cómo manejaría las excepciones de NumberFormat: en los datos de configuración de la aplicación web:

loadCertainProperty(String propVal) { try { val = Integer.parseInt(userdata); return val; } catch (NumberFormatException nfe) { // RuntimeException need not be declared throw new RuntimeException("Property certainProperty in your configuration is expected to be " + " an integer, but was ''" + propVal + "''. Please correct your " + "configuration and start again"); // After starting an enterprise application the sysadmin should always check availability // and can now correct the property value } }

En una GUI:

public int askValue() { // TODO add opt-out button; see Swing docs for standard dialog handling boolean valueOk = false; while(!valueOk) { try { String val = dialog("Please enter integer value for FOO"); val = Integer.parseInt(userdata); return val; } catch (NumberFormatException nfe) { // Ignoring this; I don''t care how many typo''s the customer makes } } }

En un formulario web: devuelva el formulario al usuario con un útil mensaje de error y la posibilidad de corregirlo. La mayoría de los marcos ofrecen una forma estandarizada de validación.


Eso es más o menos, aunque devolver MIN_VALUE es algo cuestionable, a menos que estés seguro de que es lo correcto para usar para lo que esencialmente estás usando como un código de error. Sin embargo, al menos documentaría el comportamiento del código de error.

También podría ser útil (según la aplicación) registrar la entrada incorrecta para que pueda rastrear.


Estoy seguro de que es mala forma, pero tengo un conjunto de métodos estáticos en una clase de Utilidades que hacen cosas como Utilities.tryParseInt(String value) que devuelve 0 si la cadena no se puede leer y Utilities.tryParseInt(String value, int defaultValue) que le permite especificar un valor para usar si parseInt() arroja una excepción.

Creo que hay momentos en los que devolver un valor conocido con malas entradas es perfectamente aceptable. Un ejemplo muy artificial: le pides al usuario una fecha en el formato AAAAMMDD y te dan una mala información. Puede ser perfectamente aceptable hacer algo como Utilities.tryParseInt(date, 19000101) o Utilities.tryParseInt(date, 29991231); dependiendo de los requisitos del programa.


Integer.MIN_VALUE como NumberFormatException es una mala idea.

Puede agregar una propuesta a Project Coin para agregar este método a Entero

@Nullable public static Entero parseInteger (String src) ... devolverá nulo por mala entrada

¡Luego ponga un enlace a su propuesta aquí y todos votaremos!

PD: mira esto http://msdn.microsoft.com/en-us/library/bb397679.aspx esto es lo feo e hinchado que podría ser


Le pregunté si había librerías de código abierto que tenían métodos para hacer este análisis y la respuesta es ¡sí!

Desde Apache Commons Lang puede usar NumberUtils.toInt :

// returns defaultValue if the string cannot be parsed. int i = org.apache.commons.lang.math.NumberUtils.toInt(s, defaultValue);

Desde Google Guava puedes usar Ints.tryParse :

// returns null if the string cannot be parsed // Will throw a NullPointerException if the string is null Integer i = com.google.common.primitives.Ints.tryParse(s);

No es necesario escribir sus propios métodos para analizar los números sin arrojar excepciones.


Para los datos suministrados por el usuario, Integer.parseInt es generalmente el método incorrecto porque no admite la internacionalización. El paquete java.text es tu amigo (detallado).

try { NumberFormat format = NumberFormat.getIntegerInstance(locale); format.setParseIntegerOnly(true); format.setMaximumIntegerDigits(9); ParsePosition pos = new ParsePosition(0); int val = format.parse(str, pos).intValue(); if (pos.getIndex() != str.length()) { // ... handle case of extraneous characters after digits ... } // ... use val ... } catch (java.text.ParseFormatException exc) { // ... handle this case appropriately ... }


Podría usar un Entero, que puede establecerse como nulo si tiene un valor incorrecto. Si está utilizando java 1.6, proporcionará auto boxing / unboxing para usted.


Pon algunas declaraciones if delante de ella. if (null! = userdata)


Pruebe org.apache.commons.lang.math.NumberUtils.createInteger(String s) . Eso me ayudó mucho. Existen métodos similares para dobles, anhelos, etc.


Si puedes evitar las excepciones probando de antemano como dijiste (isParsable ()) podría ser mejor, pero no todas las bibliotecas fueron diseñadas con eso en mente.

Utilicé tu truco y apesta porque las huellas de pila en mi sistema integrado se imprimen independientemente de si las capturas o no :(


Voy a replantear el punto que stinkyminky estaba haciendo hacia el final de la publicación:

Un enfoque generalmente aceptado que valida la entrada del usuario (o la entrada de archivos de configuración, etc.) es usar la validación antes de procesar realmente los datos. En la mayoría de los casos, este es un buen movimiento de diseño, aunque puede dar lugar a múltiples llamadas a algoritmos de análisis sintáctico.

Una vez que sepa que ha validado correctamente la entrada del usuario, entonces es seguro analizarlo e ignorar, registrar o convertir a RuntimeException la NumberFormatException.

Tenga en cuenta que este enfoque requiere que considere su modelo en dos partes: el modelo de negocio (donde realmente nos importa tener valores en formato int o float) y el modelo de interfaz de usuario (donde realmente queremos permitir que el usuario ponga lo que sea querer).

Para que los datos migren del modelo de interfaz de usuario al modelo comercial, deben pasar por un paso de validación (esto puede ocurrir campo por campo, pero la mayoría de los escenarios requieren validación en todo el objeto que se está configurando) .

Si falla la validación, se le presentan comentarios al usuario informándoles sobre lo que han hecho mal y se les da la oportunidad de solucionarlo.

Bibliotecas de encuadernación como JGoodies Binding y JSR 295 hacen que este tipo de cosas sea mucho más fácil de implementar de lo que parece, y muchos frameworks web proporcionan construcciones que separan la entrada del usuario del modelo de negocio real, solo poblando objetos comerciales una vez completada la validación.

En términos de validación de archivos de configuración (el otro caso de uso presentado en algunos de los comentarios), una cosa es especificar un valor predeterminado si un valor particular no se especifica en absoluto, pero si los datos están formateados incorrectamente (alguien escribe un '' oh ''en lugar de'' cero ''- o copiaron de MS Word y todos los back-ticks obtuvieron un funky carácter unicode), entonces se necesita algún tipo de retroalimentación del sistema (incluso si solo está fallando la aplicación lanzando una excepción de tiempo de ejecución) .