java - 是否可以创建一个等待整个 try block 执行的 catch block ?

标签 java parsing exception try-catch

我在做什么

我正在尝试制作一个更清晰的嵌套 try catch block 版本,并且在这样做的同时解决了一个非常基本的异常问题。我正在制作一个可以做很多事情的计算器。但在此之前,它必须将用户输入作为字符串接收,并将其转换为 float 或整数。我通过简单地调用 java 的内置 parseInt 和 parseFloat 函数来做到这一点。现在我正在使用嵌套的 try catch block 来执行此操作:

String stringToParse = "1.0"
try{Integer.parseInt(stringToParse);}
catch(NumberFormatException n){
    try{Float.parseFloat(stringToParse);}
    catch(NumberFormatException n){
        System.out.println(n)
        }
    }

为什么这是一个问题?

这对我来说很困惑,我宁愿有一个 try block 来收集错误,但不会立即转到 catch block ,而是执行整个 try 并在执行 try 后捕获任何错误。我自己制作了一个可运行的示例,它显示了我想要的内容:

    String num = "1.0";
    int i = 0;
    ArrayList<Object> listofResults = new ArrayList<>();
    ArrayList<Integer> listOfErrorIndices = new ArrayList<>();
    try {
        listofResults.add(Integer.parseInt(num));
        i++;
        listofResults.add(Float.parseFloat(num));
        i++;
        listofResults.add(Integer.parseInt(num));
    } catch (NumberFormatException n) {
        listOfErrorIndices.add(i);
    }
    for (Integer element:listOfErrorIndices) {
        System.out.println(element);
        //this currently prints out 0 and I want it to print out both 0 and 
        //2 so that it catches both errors.
    }

我对如何解决问题的想法/我尝试过的其他方法

我的计划是收集尝试中抛出的所有 NumberFormatException 索引 (i) 的列表。每次我尝试解析字符串时,都会将一个元素添加到 resultsList 中。我的目标是使用这个理论上的 try catch block 来获取所有异常的索引,然后在抛出错误时将它们从 resultsList 中删除。太长了;现在上面的代码打印出 0,我希望它打印出 0 和 2。基本上,我不使用嵌套的 try catch block ,而是使用列表理解和带有 i 的异常处理索引来删除错误结果,只保留好的结果。我不知道这是否可能,因此提出这个问题。我看过“更好的方法来实现嵌套的 try catch block ”问题,但是它对我来说没有用,因为它在 delphi 中提供了一个解决方案,我不明白它到底是如何工作的,或者它是否按照我的方式工作希望我的工作。我一开始认为finally block 可能是我需要的,但它只在执行catch之后运行,或者如果没有异常,在try之后运行。我需要一些东西来推迟 catch block ,直到尝试完成,但我无法想到/找到任何可以做到这一点的东西。

你疯了吗?

现在你可能会问,这到底有什么意义?想象一下,如果您遇到上述问题,但您没有使用两种方法来解析字符串,而是使用了 10 或 100 个字符串。很快,使用嵌套的 try catch block 进行异常处理几乎是不可能的。我见过解决方案,其中 catch block 调用自定义异常方法,然后至少处理错误的格式。它看起来像这样:

try{
//bad code
}
catch{
    trysomethingelse();
}
trysomethingelse(){
//equally bad code
catch{
//ya done screwed up son
}
}

但是我不满意,因为这意味着您需要一百万个不同的方法名称才能处理一个错误。想象一下,错误总是相同的,您只需要尝试 100 种不同的字符串解析方法。如果您尝试将字符串转换为数字,它总是会出现 numberformatException,那么为什么要为相同的错误设置一百万个 catch block 呢?我想尝试使用一个理论上的 catch block 来执行此操作,该 block 指定在 try block 中多次发生的一个错误。

最佳答案

您构建一个解析器列表/数组,然后迭代该列表,捕获每个解析器的异常。

使用 Java 8 方法引用,这非常简单。首先,定义一个允许抛出异常的Parser功能接口(interface):

@FunctionalInterface
public interface Parser {
    Object parse(String text) throws Exception;
}

接下来,构建要尝试的解析器数组:

Parser[] parsers = {
        Integer::valueOf,
        Double::valueOf,
        BigInteger::new,
        BigDecimal::new
};

最后,一次尝试一个:

String text = "45.8";

Object[] results = new Object[parsers.length];
for (int i = 0; i < parsers.length; i++) {
    try {
        results[i] = parsers[i].parse(text);
    } catch (Exception e) {
        results[i] = e;
    }
}

现在您可以查看结果:

for (Object result : results) {
    if (result instanceof Exception)
        System.out.println("Error: " + result);
    else
        System.out.println("Parsed as " + result.getClass().getSimpleName() + ": " + result);
}

输出

Error: java.lang.NumberFormatException: For input string: "45.8"
Parsed as Double: 45.8
Error: java.lang.NumberFormatException: For input string: "45.8"
Parsed as BigDecimal: 45.8

或者将解析后的对象和异常放入两个不同的列表中。由你决定。

关于java - 是否可以创建一个等待整个 try block 执行的 catch block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51885024/

相关文章:

php: 从 html 中解析字符串

javascript - 查看传递给抛出异常的构造函数的字符串

java - 我如何使用 git 在 Intellij 中管理 workspace.xml

java - 为什么我的 IDE 可以找到 JAR,但我的命令行却找不到?

java - 获取标签之间的子字符串

java - 在 JFrame MessageBox 中给出计算结果

java - Android onTouchListener 不适用于嵌套 switch 语句

java - JUnit4 使用测试套件运行特定包中的所有测试

exception - NotFoundException 的 HTTP 状态代码 500

c++ - 添加到多个 std 容器时 C++ 中的异常安全