Dans un certain bloc try, j'ai deux variables String
qui pourraient causer NumberFormatException
quand je sais utiliser Integer.parseInt(string1)
etInteger.parseInt(string2)
. La question est, si je catch
une exception, comment savoir quelle chaîne est le fauteur de troubles? J'ai besoin du nom de la variable du fauteur de troubles.
Voici un exemple de code:
public class test {
public static void main(String[] args) {
try {
String string1 = "fdsa";
String string2 = "fbbbb";
Integer.parseInt(string1);
Integer.parseInt(string2);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
Et la méthode e.printStackTrace()
ne me dit pas le nom de la variable; il me dit simplement le contenu du fauteur de troubles.
Java.lang.NumberFormatException: pour la chaîne d'entrée: "fdsa" à Java.lang.NumberFormatException.forInputString (NumberFormatException.Java:65) à Java.lang.Integer.parseInt (Integer.Java:580) à Java.lang.Integer.parseInt (Integer.Java:615) à test.main (test.Java:9) à Sun.reflect.NativeMethodAccessorImpl.invoke0 (Méthode native) à Sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.Java:62) à Sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.Java:43) à Java.lang.reflect.Method.invoke (Method.Java:498) à com.intellij.rt.execution.application.AppMain.main (AppMain.Java:147)
Processus terminé avec le code de sortie 0
La raison pour laquelle j'ai besoin de connaître le nom de la variable est que je dois informer l'utilisateur de ce qui se passe. Par exemple, indiquez à l'utilisateur que chaîne1 est erronée à l'aide de
System.out.println(troubleMakerName + "is wrong!")
Dans mes exigences, l'utilisateur doit entrer
fd=(fileName,maxLength,minLength)
ensuite, j'analyserai la chaîne d'entrée et créerai des réponses. Je voudrais donc vérifier si les variables maxLength
et minLength
jetteront NumberFormatException
. Dans ce cas, si minLength
a un problème, je dois informer l'utilisateur que minLength est incorrect.
Vous rencontrez un problème XY .
Vous ne voulez pas lire le nom de la variable réelle. Vous voulez pouvoir valider les entrées et donner des messages d'erreur raisonnables à votre utilisateur.
String fileName, maxLengthInput, minLengthInput;
int maxLength, minLength;
List<String> errors = new ArrayList<>();
try {
maxLength = Integer.parseInt(maxlengthInput);
} catch (NumberFormatException nfe) {
errors.add("Invalid input for maximum length, input is not a number");
}
try {
minLength = Integer.parseInt(minlengthInput);
} catch (NumberFormatException nfe) {
errors.add("Invalid input for minimum length, input is not a number");
}
// show all error strings to the user
Ne pas lancer les exceptions directement mais les collecter vous permet d'informer l'utilisateur de toutes les entrées non valides en même temps (peut-être mettre en surbrillance les champs associés en rouge) au lieu de les laisser corriger une entrée, essayer de soumettre à nouveau, puis de voir qu'une autre entrée est également faux.
Au lieu de Strings, vous pouvez utiliser votre propre structure de données contenant des informations sur le champ concerné, etc., mais cela sort rapidement de la portée. Le Gist principal est le suivant: utilisez deux blocs try-catch et vous pourrez différencier les champs erronés.
Si plusieurs entrées sont impliquées, vous pouvez reformuler ceci dans une boucle.
Utilisez 2 blocs try
, catch
séparés pour analyser deux entrées pour chaque variable. Générez ensuite le message de vérification d'intégrité à l'intérieur de chaque bloc catch
.
String string1 = "fdsa";
String string2 = "fbbbb";
try {
Integer.parseInt(string1);
} catch (NumberFormatException e) {
e.printStackTrace();
**//Please provide a valid integer for string1**
}
try {
Integer.parseInt(string2 );
} catch (NumberFormatException e) {
e.printStackTrace();
**//Please provide a valid integer for string2**
}
J'aimerais écrire ma propre méthode parseInt
:
public static int parseInt(String s,
Supplier<? extends RuntimeException> supplier) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
throw (RuntimeException)supplier.get().initCause(e);
}
}
Comme je le sais, nous ne pouvons pas lire un nom de variable par réflexion, je passe donc plutôt un littéral String
:
parseInt(string1, () -> new NumberFormatException("string1"));
Je vais laisser la réponse d'origine et fournir une version qui a discuté dans les commentaires. Mais pour le moment, je ne comprends pas pourquoi un fournisseur est excessif.
public static int parseInt(String s, String message) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
throw (NumberFormatException)new NumberFormatException(message).initCause(e);
// throw new IllegalArgumentException(message, e);
}
}
Son appel ressemble à
parseInt(string1, "string1");
Avant de réaliser l'opération, vous pouvez écrire une simple fonction isInteger () pouvant vous renvoyer un booléen. Une bonne implémentation peut être trouvée sur ce fil. Cela utilise la radix de la valeur et itère s’il s’agit d’un int et s’avère plutôt pratique . Déterminer si une chaîne est un entier en Java l'argument
Il suffit d'utiliser un autre essai de capture pour l'autre déclaration
public class test
{
public static void main(String[] args)
{
String string1 = "fdsa";
String string2 = "fbbbb";
try
{
Integer.parseInt(string1);
}
catch (NumberFormatException e)
{
System.out.println("string1 is the culprit");
e.printStackTrace();
}
try
{
Integer.parseInt(string2);
}
catch (NumberFormatException e)
{
System.out.println("string2 is the culprit");
e.printStackTrace();
}
}
}
Je suis surpris que personne n'ait proposé quelque chose comme ça:
public class test {
public static void main(String[] args) {
String errorContext;
try {
String string1 = "fdsa";
String string2 = "fbbbb";
errorContext = "string1";
Integer.parseInt(string1);
errorContext = "string2";
Integer.parseInt(string2);
} catch (NumberFormatException e) {
System.out.println(errorContext + " is wrong!")
e.printStackTrace();
}
}
}
C'est une solution très simple - simpliste, diraient certains - mais elle est également assez claire et robuste.
Si j'ai bien compris, l'objectif de cette question n'était pas de fournir un meilleur moyen de convertir des chaînes en entiers (même si cela peut effectivement exister), mais plutôt de trouver un moyen de ne pas dire que quoi est allé faux dans un long bloc try
, mais aussi (où} _ ça s'est mal passé. Si le but est d'afficher un message d'erreur significatif à l'utilisateur (suggérant idéalement quoi faire plutôt que de se plaindre que quelque chose ne va pas), alors simplement imprimer une trace de pile n'est pas suffisant, bien sûr, et essayer d'attraper chaque ligne de code n'est pas une option attrayante non plus.
Vous pouvez créer une méthode avec un test/catch qui renvoie la valeur que vous affectez ou affiche sur la console qu'il y a un problème. Ainsi, vous pouvez gérer autant de variables que vous le souhaitez avec un test/catch tout en suivant le nom de tous les variables qui causent un problème.
public class test {
public static void main(String[] args) {
String string1 = returnString("fdsa", "string1");
String string2 = returnString("fbbbb", "string2");
}
private string returnString(String input, String varName) {
String str = "";
try {
str = input;
Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("Error processing " + varName);
}
return str;
}
}
Vous devez éviter d'attraper Runtime exceptions
et utiliser un autre mécanisme d'identification des erreurs. Dans votre cas, vous pouvez utiliser Matcher et votre problème pourrait être écrit comme suit:
public class test {
private static final Pattern pattern = Pattern.compile("\\d+");
public static void main(String[] args) {
String string1 = "fdsa";
String string2 = "fbbbb";
if (pattern.matcher(string1).matches()) {
Integer.parseInt(string1);
} else {
//string1 is not an integer
}
...
}
}
Ou vous pouvez simplement écrire
boolean errorInLineOne = !pattern.matcher(string1).matches();
...
C'est assez simpliste, mais voici ma solution ..
public class test
{
public static int tryParseInt(String str) throws Exception
{
try
{
return Integer.parseInt(str);
}
catch(Exception e)
{
System.err.println("tryParseInt: couldn't parse '"+str+"'");
throw e;
}
}
public static void main(String[] args)
{
try
{
String string1 = "fdsa";
String string2 = "fbbbb";
tryParseInt(string1);
tryParseInt(string2);
}
catch (NumberFormatException e)
{
e.printStackTrace();
}
}
}