【问题标题】:Continue the flow after throwing exception抛出异常后继续流程
【发布时间】:2019-06-18 01:16:59
【问题描述】:

在我的用例中,我正在遍历地图并检查列表中是否存在特定键。如果它存在,那么我必须抛出异常,否则继续执行。

Map<A,B> myMap = new HashMap<A,B>();
//code to populate values in myMap
...
...
List<A> myList = new ArrayList<A>();
//code to populate values in myList
...
...
for(Map.Entry<A,B> eachElementInMap:myMap.entrySet()){
    if(myList.contains(eachElementInMap:myMap.getKey())){
        //throwing exception
        throw new MyCustomizedException("someString");
    }
}

//code continues
...
....

在上面的例子中,如果 map(myMap) 中有 3 个元素,其中 1 个 key 存在于 list(myList) 中,我想抛出一个异常,它应该继续执行其他代码行其余两个。我是否使用错误的设计来实现这一目标?任何帮助或建议表示赞赏!谢谢

【问题讨论】:

  • 我是否使用了错误的设计来实现这一目标? A - 是的,也许您可​​以创建一个 Exceptions/errors/whatever 列表并将其返回给调用方法

标签: java exception try-catch


【解决方案1】:

通常,一旦您抛出异常,您就是说当前执行行应该终止,而不是继续。如果你想继续执行代码,那么最好不要抛出异常。

boolean fail = false;

for (Map.Entry<A,B> eachElementInMap:myMap.entrySet()) {
    if (myList.contains(eachElementInMap:myMap.getKey())) {
        // throw an exception later
        fail = true;
    }
}

if (fail) {
    throw new MyCustomizedException("someString");
}

【讨论】:

  • 嗨@Tim Biegeleisen,在这种情况下,如果失败为真,它不会停止执行吗?
  • 是的,代码会继续执行,但它会跟踪列表是否包含一个匹配的元素,在这种情况下,它会在最后抛出异常。我提供的答案只是一个可能适合您需要的一般模式。
【解决方案2】:

您还可以在与您抛出它的位置不同的位置创建一个异常对象。在异常消息不仅仅是“someString”,而是需要从被迭代的对象获得的数据中构造的情况下,这个习语将很有用。

Optional<MyCustomizedException> exception = Optional.empty();

for (Map.Entry<A, B> eachElementInMap:myMap.entrySet()) {
    if (myList.contains(eachElementInMap.getKey())) {
        // Create an exception object that describes e.g., the missing key(s)
        // but do not throw it yet.
        if( exception.isPresent() ) {
            exception.get().addToDescription( /* Context-sensitive information */ );
        }
        else {
            exception = Optional.of(
                new MyCustomizedException( /* Context-sensitive information */));
        } 
    }
}

if( exception.isPresent() ) {
    throw exception.get();
}

如果异常中存储的唯一数据是字符串,则可以通过在StringBuilder中累积问题描述来达到等效的效果,但对于需要更多有趣数据进入异常对象的情况,请随心所欲地构建可能是一个值得考虑的选择。

【讨论】:

    【解决方案3】:

    您可以将其拆分为两个列表,failList 和successList。然后去做。

    这样更清楚

    failList = myMap.entrySet().stream().filter(p->myList.contains(p.getKey())).collect(Collectors.toList());
    successList = myMap.entrySet().stream().filter(p->!myList.contains(p.getKey())).collect(Collectors.toList());
    
           failList.forEach(p -> {
                // fail code
            });
           successList .forEach(p -> {
                // success code
            });
    

    【讨论】:

      【解决方案4】:

      为什么不使用 if...else 而不是 try catch ?错误只是意味着这是一个错误。如果你害怕犯一些你不知道的错误。你可以使用抛出错误。

      不管怎样,程序运行时不应该使用它

      【讨论】:

        猜你喜欢
        • 2021-05-13
        • 2015-10-31
        • 1970-01-01
        • 2012-03-08
        • 2015-03-10
        • 2012-09-15
        • 2012-04-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多