41 votes

Comment savoir quelle variable est le coupable dans le bloc try ?

Dans un certain bloc d'essai, j'ai deux String variables qui pourraient causer NumberFormatException lorsque j'utilise Integer.parseInt(string1) et Integer.parseInt(string2) . La question est, si je catch une exception, comment savoir quelle chaîne est le fauteur de troubles ? J'ai besoin d'obtenir le 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 juste le contenu du trouble-fête.

java.lang.NumberFormatException : Pour la chaîne d'entrée : "fdsa" à java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:580) at java.lang.Integer.parseInt(Integer.java:615) at test.main(test.java:9) at sun.reflect.NativeMethodAccessorImpl.invoke0(Méthode native) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) à l'adresse sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Le processus s'est terminé avec le code de sortie 0

La raison pour laquelle je dois connaître le nom de la variable est que je dois demander à l'utilisateur ce qui se passe. Par exemple, dire à l'utilisateur que la chaîne de caractères 1 est fausse en utilisant

System.out.println(troubleMakerName + "is wrong!")

Dans mes exigences, l'utilisateur doit saisir

fd=(fileName,maxLength,minLength)

puis je vais analyser la chaîne d'entrée et créer des réponses. J'aimerais donc vérifier si le maxLength y minLength jettera NumberFormatException . Dans ce cas, si minLength a quelque chose d'erroné, alors je dois avertir l'utilisateur que la longueur minimale est incorrecte.

69voto

Polygnome Points 4766

Vous avez un Problème XY .

Vous ne voulez pas lire le nom réel de la variable. Vous voulez être capable de valider l'entrée et de 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

Le fait de ne pas lancer directement les exceptions mais de les collecter vous permet d'informer l'utilisateur de toutes les entrées non valides en une seule fois (peut-être en mettant en évidence les champs concernés par une couleur rouge) au lieu de lui demander de corriger une entrée, d'essayer de soumettre à nouveau, puis de constater qu'une autre entrée est également incorrecte.

Au lieu d'utiliser des chaînes de caractères, vous pourriez utiliser votre propre chaîne de données contenant des informations sur le champ concerné, mais cela dépasse rapidement le cadre de l'application. L'essentiel est d'utiliser deux blocs try-catch, et vous êtes en mesure de différencier le champ qui est en erreur.

S'il y a plus d'entrées, vous pouvez transformer cela en une boucle.

10voto

chandpriyankara Points 909

Utilisez deux try , catch pour analyser deux entrées pour chaque variable. Ensuite, le message de vérification de l'intégrité est généré dans chaque bloc catch bloc.

        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** 
        }

6voto

Andrew Tobilko Points 1283

Je voudrais écrire mon propre parseInt méthode :

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 le nom d'une variable par réflexion, donc je passe simplement un fichier String à la place :

parseInt(string1, () -> new NumberFormatException("string1"));

Je vais laisser la réponse d'origine et fournir une version qui a été discutée dans les commentaires. Mais pour l'instant, je ne comprends pas pourquoi un fournisseur est une surcharge.

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");

4voto

Ramachandran.A.G Points 2644

Avant d'effectuer l'opération, vous pouvez écrire une simple fonction isInteger() qui peut vous renvoyer un booléen. Une bonne implémentation peut être trouvée sur ce fil de discussion. Cette fonction utilise le radix de la valeur et itère si c'est un int, ce qui est assez pratique. Déterminer si une chaîne est un nombre entier en Java Un simple "si" conditionnel "alors" peut trouver la valeur qui est en défaut dans l'argument.

3voto

Black Points 3971

Il suffit d'utiliser un autre try catch 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();
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X