如何知道哪个变量是try块的罪魁祸首?

时间:2016-07-28 07:45:57

标签: java exception exception-handling

在某个试用版块中,我有两个String变量,当我用户NumberFormatExceptionInteger.parseInt(string1)时,这些变量可能会导致Integer.parseInt(string2)。问题是,如果我catch例外,如何知道哪个字符串是麻烦制造者?我需要得到麻烦制造者的变量名。

以下是一些示例代码:

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();
        }
        }
    }

方法e.printStackTrace()没有告诉我变量名;它只是告诉我麻烦制造者的内容。

  

java.lang.NumberFormatException:对于输入字符串:“fdsa”at   java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)     在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(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:498)at   com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

     

处理完成,退出代码为0

我需要知道变量名称的原因是我需要提示用户发生了什么。例如,使用

告诉用户string1是错误的
System.out.println(troubleMakerName + "is wrong!")

在我的要求中,用户应输入

fd=(fileName,maxLength,minLength)

然后我将分析输入字符串并创建一些响应。所以我想检查maxLengthminLength是否会抛出NumberFormatException。在这种情况下,如果minLength出错了,那么我需要提示用户minLength是错误的。

9 个答案:

答案 0 :(得分:69)

您正在使用XY-Problem

您不想阅读实际的变量名称。您希望能够验证输入并向用户提供合理的错误消息。

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

不直接抛出异常但是收集异常允许您一次通知用户所有无效输入(可能用红色突出显示相关字段)而不是让他们修复一个输入,尝试再次提交,然后再看另一个输入也是错误的。

您可以使用自己的数据结构代替字符串,其中包含相关字段等的信息,但很快就会超出范围。主要要点是:使用两个try-catch块,您可以区分哪个字段是错误的。

如果涉及更多输入,您可以将其重构为循环。

答案 1 :(得分:10)

使用2个单独的trycatch块来解析每个变量的两个输入。然后在每个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** 
        }

答案 2 :(得分:6)

我想编写自己的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);
    }
}

据我所知,我们无法通过反射读取变量名称,因此我只是传递String字面值:

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

我将留下原始答案并提供评论中讨论过的版本。但就目前而言,我很困惑为什么供应商是一种过度杀伤。

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

它的调用看起来像

parseInt(string1, "string1");

答案 3 :(得分:4)

在执行操作之前,您可以编写一个简单的isInteger()函数,它可以返回一个布尔值。在这个线程上可以找到一个很好的实现。这使用值的基数,如果它是一个int则迭代并且非常方便。 Determine if a String is an Integer in Java 一个简单的if条件然后可以在参数

中找到哪个值是流氓

答案 4 :(得分:3)

只需使用另一个try catch来获取其他语句

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();
        }
    }
}

答案 5 :(得分:2)

您可以使用try / catch创建一个方法,该方法返回您指定的值或打印到控制台以确定存在问题,这样您就可以在需要时使用一个try / catch来容纳尽可能多的变量,同时仍然可以跟踪导致问题的所有变量的名称。

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

答案 6 :(得分:2)

我很惊讶没人提出这样的事情:

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();
    }
    }
}

这是一个非常简单的解决方案 - 简单,有些人会说 - 但它也相当清晰和强大。

这个问题的重点 - 正如我所理解的 - 不是提供一种更好的方法将字符串转换为整数(即​​使它确实可能存在),而是找到一种方法来说明 what < / em>在一个很长的try块中出错,但出现它出错了。如果一个人的目标是向用户显示一个有意义的错误消息(理想情况下建议做什么而不仅仅是抱怨某些事情是错误的),那么仅仅打印一个堆栈跟踪是不够的,当然,并尝试捕获每一行代码也不是一个有吸引力的选择。

答案 7 :(得分:0)

您应该避免捕获运行时异常并使用其他一些机制来识别错误。在您的情况下,您可以使用匹配器,您的问题可以写成:

&#xA;&#xA;
 公共类测试{&#xA;&#xA; private static final Pattern pattern = Pattern.compile(“\\ d +”);&#xA; public static void main(String [] args){&#xA; String string1 =“fdsa”;&#xA; String string2 =“fbbbb”;&#xA; if(pattern.matcher(string1).matches()){&#xA;的Integer.parseInt(字符串1);&#XA; } else {&#xA; // string1不是整数&#xA; }&#XA; ...&#XA; }&#xA;}&#xA;  
&#xA;&#xA;

或者你可以写

&#xA;&#xA;
 < code> boolean errorInLineOne =!pattern.matcher(string1).matches();&#xA; ...&#xA;  
&#xA;

答案 8 :(得分:0)

这很简单,但这是我的解决方案..

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();
        }
    }
}