如何知道哪个variables是try块中的罪魁祸首?

在某个try块中,我有两个Stringvariables,当我用户Integer.parseInt(string1)Integer.parseInt(string2)时,可能会导致NumberFormatException 。 问题是,如果我发现一个例外,怎么知道哪个string是麻烦制造者? 我需要得到麻烦制造者的variables名称。

以下是一些示例代码:

 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()方法不会告诉我variables的名字; 它只是告诉我这个麻烦制造者的内容。

java.lang.NumberFormatException:对于inputstring:java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)处的“fdsa”位于java.lang.Integer处的java.lang.Integer.parseInt(Integer.java:580)。在sun.reflect.NativeMethodAccessorImpl.invoke0(本地方法)sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)在sun.reflect处的test.main(test.java:9)处的parseInt(Integer.java:615) .DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)java.lang.reflect.Method.invoke(Method.java:498)

进程使用退出码0结束

我需要知道variables名称的原因是我需要提示用户发生了什么事情。 例如,通过使用告诉用户string1是错误的

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

在我的要求中,用户应该input

 fd=(fileName,maxLength,minLength) 

那么我将分析input的string并创build一些响应。 所以我想检查maxLengthminLength是否会抛出NumberFormatException 。 在这种情况下,如果minLength有问题,那么我需要提示用户minLength是错误的。

你有一个XY-问题 。

你不想读取实际的variables名称。 您希望能够validationinput并向用户提供合理的错误消息。

 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 

不直接抛出exception,但收集它们可以让你立即通知用户所有的无效input(也许用红色突出相关的字段),而不是让他们修复一个input,试图再次提交,然后看到另一个input也是错的。

你可以使用你自己的数据结构来包含相关领域的信息,而不是string,但这很快就会超出范围。 主要的要点是:使用两个try-catch块,你可以区分哪个域是错误的。

如果涉及更多的input,可以将其重构为一个循环。

使用2个单独的trycatch块为每个variablesparsing两个input。 然后在每个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** } 

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

据我所知,我们不能通过reflection来读取variables名,所以我只是传递一个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"); 

在执行操作之前,您可以编写一个简单的isInteger()函数,它可以返回一个布尔值。 在这个线程上可以find一个好的实现。 这使用值的基数,如果它是一个int并且非常方便,则迭代。 确定一个string是否是Java中的整数如果条件简单,那么可以在参数中find哪个值是stream氓

只要使用另一个尝试捕获其他语句

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

你可以用try / catch方法创build一个方法,返回你赋值或者打印到控制台的值,这样你就可以容纳尽可能多的variables,只需要一个try / catch,而仍然跟踪所有的名字导致问题的variables。

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

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

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

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

根据我的理解,这个问题的重点不在于提供将string转换为整数的更好的方法(即使它确实存在),而是要find一种方法来说明不仅在长的try块中出错,还有哪里出错了。 如果一个人的目标是向用户显示一个有意义的错误信息(理想的是build议做什么,而不是仅仅抱怨有什么错误),那么只需打印一个堆栈跟踪是不够的,并且尝试捕获每一行代码也不是一个有吸引力的select。

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

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

或者你可以写

 boolean errorInLineOne = !pattern.matcher(string1).matches(); ... 

这是相当简单的,但这是我的解决scheme..

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