在某个试用版块中,我有两个String
变量,当我用户NumberFormatException
和Integer.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)
然后我将分析输入字符串并创建一些响应。所以我想检查maxLength
和minLength
是否会抛出NumberFormatException
。在这种情况下,如果minLength
出错了,那么我需要提示用户minLength是错误的。
答案 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个单独的try
,catch
块来解析每个变量的两个输入。然后在每个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; 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();
}
}
}