如何知道哪个variables是try块中的罪魁祸首?
在某个try块中,我有两个String
variables,当我用户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一些响应。 所以我想检查maxLength
和minLength
是否会抛出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个单独的try
, catch
块为每个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(); } } }
- 好的方法来封装Integer.parseInt()
- C ++中的exception对象范围
- 使用macros或键盘快捷键切换“抛出exception时中断”
- 有没有可能在java中捕捉到内存exception?
- java.lang.IllegalStateException:找不到工厂javax.faces.application.ApplicationFactory的备份
- 在synchronized子句中抛出exception的副作用?
- 在swift中捕获无效用户input的exception
- 处理“java.lang.OutOfMemoryError:PermGen空间”错误
- C#中的exception有多昂贵?